/** * Gets the version of the object at the time of the failed command. * * {@include.example io.sphere.sdk.errors.SphereExceptionIntegrationTest#concurrentModification()} * * @return version or null */ @Nullable public Long getCurrentVersion() { final List<? extends SphereError> errors = getErrors(); return ObjectUtils.defaultIfNull(errors, Collections.emptyList()).stream() .map(errror -> (SphereError) errror) .filter(error -> ConcurrentModificationError.CODE.equals(error.getCode())) .map(error -> error.as(ConcurrentModificationError.class).getCurrentVersion()) .findFirst() .orElse(null); } }
public static SphereError of(final String code, final String message) { return new SphereError(code, message); }
public <T extends SphereError> T as(final Class<T> errorClass) { final Optional<String> classErrorCodeOption = codeValueOf(errorClass); if (classErrorCodeOption.map(classErrCode -> classErrCode.equals(code)).orElse(true)) { final ObjectMapper objectMapper = SphereJsonUtils.newObjectMapper(); final JsonNode jsonNode = objectMapper.createObjectNode() .put("code", code) .put("message", message) .setAll(furtherFields); return SphereJsonUtils.readObject(jsonNode, errorClass); } else { throw new IllegalArgumentException(classErrorCodeOption.map( code -> "Codes not matching: " + code + " is not " + getCode()) .orElse("error class not mathing code " + getCode())); } }
@Override protected boolean matchesSafely(final ErrorResponseException e) { boolean matches = false; if (!e.getErrors().isEmpty()) { final SphereError firstError = e.getErrors().get(0); try { firstError.as(error); matches = true; } catch (final IllegalArgumentException e1) { matches = false; } } return matches; }
private boolean isRecoverableException(final Throwable throwable) { if (throwable != null) { final Throwable cause = throwable.getCause(); return cause instanceof ConcurrentModificationException || (cause instanceof ErrorResponseException && ((ErrorResponse) cause).getErrors().stream().anyMatch(e -> e.getCode().equals(DuplicateFieldError.CODE))); } return true; }
@Test public void notMatchingError() throws Exception { final String json = "{\n" + " \"statusCode\" : 400,\n" + " \"message\" : \"Message.\",\n" + " \"errors\" : [ {\n" + " \"code\" : \"OtherCode\",\n" + " \"message\" : \"Message.\"" + " } ]\n" + "}"; final ErrorResponse sphereErrorResponse = SphereJsonUtils.readObject(json, ErrorResponse.typeReference()); assertThatThrownBy(() -> sphereErrorResponse.getErrors().get(0).as(InvalidJsonInputError.class)) .isInstanceOf(IllegalArgumentException.class); } }
default boolean hasErrorCode(final String errorCode) { return getErrors().stream().anyMatch(sphereError -> sphereError.getCode().equals(errorCode)); }
@Test public void customerAlreadyRegistered() { withCustomer(client(), customer -> { final String email = customer.getEmail(); final CustomerDraftDsl draft = CustomerDraftBuilder.of(email, "secret") .build(); final CustomerCreateCommand cmd = CustomerCreateCommand.of(draft); final Throwable throwable = catchThrowable(() -> client().executeBlocking(cmd)); assertThat(throwable).isInstanceOf(ErrorResponseException.class); final ErrorResponseException e = (ErrorResponseException) throwable; assertThat(e.getErrors().get(0).getCode()).isEqualTo(DuplicateFieldError.CODE); final DuplicateFieldError error = e.getErrors().get(0).as(DuplicateFieldError.class); assertThat(error.getDuplicateValue()).isEqualToIgnoringCase(email); assertThat(error.getField()).isEqualTo("email"); }); } }
@Test public void castToConcreteError() throws Exception { final String json = "{\n" + " \"statusCode\" : 400,\n" + " \"message\" : \"Request body does not contain valid JSON.\",\n" + " \"errors\" : [ {\n" + " \"code\" : \"InvalidJsonInput\",\n" + " \"message\" : \"Request body does not contain valid JSON.\",\n" + " \"detailedErrorMessage\" : \"detailed error message\"" + " } ]\n" + "}"; final ErrorResponse sphereErrorResponse = SphereJsonUtils.readObject(json, ErrorResponse.typeReference()); final InvalidJsonInputError jsonError = sphereErrorResponse.getErrors().get(0).as(InvalidJsonInputError.class); assertThat(jsonError.getDetailedErrorMessage()).isEqualTo("detailed error message"); }
@Test public void order() { withTaxedProduct(client(), product -> { final int itemsLeft = 3; final String sku = getSku(product); client().executeBlocking(InventoryEntryCreateCommand.of(InventoryEntryDraft.of(sku, itemsLeft))); final int itemCountToOrder = 5; final CartDraftDsl draft = CartDraft.of(DefaultCurrencyUnits.EUR) .withCountry(CountryCode.DE) .withInventoryMode(InventoryMode.RESERVE_ON_ORDER) .withShippingAddress(Address.of(CountryCode.DE)) .withLineItems(Collections.singletonList(LineItemDraft.of(product, 1, itemCountToOrder))); final Cart cart = client().executeBlocking(CartCreateCommand.of(draft)); final Throwable throwable = catchThrowable(() -> client().executeBlocking(OrderFromCartCreateCommand.of(cart))); assertThat(throwable).isInstanceOf(ErrorResponseException.class); final ErrorResponseException e = (ErrorResponseException) throwable; assertThat(e.hasErrorCode(OutOfStockError.CODE)); final OutOfStockError outOfStockError = e.getErrors().stream() .filter(err -> err.getCode().equals(OutOfStockError.CODE)) .findFirst().get().as(OutOfStockError.class); assertThat(outOfStockError.getSkus()).containsExactly(sku); assertThat(outOfStockError.getLineItems()).containsExactly(cart.getLineItems().get(0).getId()); }); }
@Test public void requiredValidation() { final FieldDefinition stringFieldDefinition = FieldDefinition.of(StringFieldType.of(), STRING_FIELD_NAME, en("label"), true, TextInputHint.SINGLE_LINE); final String typeKey = randomKey(); final TypeDraft typeDraft = TypeDraftBuilder.of(typeKey, en("name of the custom type"), TYPE_IDS) .description(en("description")) .fieldDefinitions(asList(stringFieldDefinition)) .build(); final Type type = client().executeBlocking(TypeCreateCommand.of(typeDraft)); withCategory(client(), category -> { assertThatThrownBy(() -> client().executeBlocking(CategoryUpdateCommand.of(category, SetCustomType.ofTypeIdAndObjects(type.getId(), Collections.emptyMap())))) .isInstanceOf(ErrorResponseException.class) .matches(e -> { final ErrorResponseException errorResponseException = (ErrorResponseException) e; final String errorCode = RequiredField.CODE; return errorResponseException.hasErrorCode(errorCode) && errorResponseException.getErrors().stream() .filter(err -> err.getCode().equals(errorCode)) .anyMatch(err -> STRING_FIELD_NAME.equals(err.as(RequiredField.class).getField())); }); }); client().executeBlocking(TypeDeleteCommand.of(type)); }