Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
*/
public class HttpMessageNotReadableProblemResolver extends AbstractProblemResolver {

private final TypeNameMapper typeNameMapper;
private final JacksonErrorHelper jacksonErrorHelper;

/** Creates a new {@link HttpMessageNotReadableProblemResolver} with default problem format. */
public HttpMessageNotReadableProblemResolver() {
Expand All @@ -74,7 +74,7 @@ public HttpMessageNotReadableProblemResolver(ProblemFormat problemFormat) {
public HttpMessageNotReadableProblemResolver(
ProblemFormat problemFormat, TypeNameMapper typeNameMapper) {
super(HttpMessageNotReadableException.class, problemFormat);
this.typeNameMapper = typeNameMapper;
this.jacksonErrorHelper = new JacksonErrorHelper(problemFormat, typeNameMapper);
}

/**
Expand All @@ -92,7 +92,7 @@ public HttpMessageNotReadableProblemResolver(
public ProblemBuilder resolveBuilder(
ProblemContext context, Exception ex, HttpHeaders headers, HttpStatusCode status) {
if (ex.getCause() instanceof MismatchedInputException e) {
return JacksonErrorHelper.resolveMismatchedInput(e, typeNameMapper);
return jacksonErrorHelper.resolveMismatchedInput(e);
}
return Problem.builder().status(HttpStatus.BAD_REQUEST.value());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,28 @@
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import io.github.problem4j.core.Problem;
import io.github.problem4j.core.ProblemBuilder;
import io.github.problem4j.spring.web.ProblemFormat;
import io.github.problem4j.spring.web.TypeNameMapper;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;

/**
* Utility for Jackson exceptions used in situations where these exceptions are the {@code cause} of
* the exception that is being resolved.
*/
final class JacksonErrorHelper {

static ProblemBuilder resolveMismatchedInput(
MismatchedInputException e, TypeNameMapper typeNameMapper) {
private final ProblemFormat problemFormat;
private final TypeNameMapper typeNameMapper;

JacksonErrorHelper(ProblemFormat problemFormat, TypeNameMapper typeNameMapper) {
this.problemFormat = problemFormat;
this.typeNameMapper = typeNameMapper;
}

ProblemBuilder resolveMismatchedInput(MismatchedInputException e) {
Optional<String> optionalProperty = resolvePropertyPath(e);

ProblemBuilder builder = Problem.builder().status(HttpStatus.BAD_REQUEST.value());
Expand All @@ -47,15 +59,15 @@ static ProblemBuilder resolveMismatchedInput(
property -> {
String kind = typeNameMapper.map(e.getTargetType()).orElse(null);

builder.detail(TYPE_MISMATCH_DETAIL);
builder.detail(problemFormat.formatDetail(TYPE_MISMATCH_DETAIL));
builder.extension(PROPERTY_EXTENSION, property);
builder.extension(KIND_EXTENSION, kind);
});

return builder;
}

private static Optional<String> resolvePropertyPath(MismatchedInputException e) {
private Optional<String> resolvePropertyPath(MismatchedInputException e) {
String property =
e.getPath().stream()
.map(JsonMappingException.Reference::getFieldName)
Expand All @@ -64,6 +76,4 @@ private static Optional<String> resolvePropertyPath(MismatchedInputException e)

return StringUtils.hasLength(property) ? Optional.of(property) : Optional.empty();
}

private JacksonErrorHelper() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class ServerWebInputProblemResolver extends AbstractProblemResolver {

private final TypeMismatchProblemResolver typeMismatchProblemResolver;
private final MethodParameterSupport methodParameterSupport;
private final TypeNameMapper typeNameMapper;
private final JacksonErrorHelper jacksonErrorHelper;

/** Creates a new {@link ServerWebInputProblemResolver} with default problem format. */
public ServerWebInputProblemResolver() {
Expand Down Expand Up @@ -105,7 +105,7 @@ public ServerWebInputProblemResolver(
super(ServerWebInputException.class, problemFormat);
this.typeMismatchProblemResolver = typeMismatchProblemResolver;
this.methodParameterSupport = methodParameterSupport;
this.typeNameMapper = typeNameMapper;
jacksonErrorHelper = new JacksonErrorHelper(problemFormat, typeNameMapper);
}

/**
Expand Down Expand Up @@ -161,7 +161,7 @@ private ProblemBuilder tryAppendingPropertyFromMethodParameter(

private ProblemBuilder resolveDecodingException(DecodingException ex) {
if (ex.getCause() instanceof MismatchedInputException e) {
return JacksonErrorHelper.resolveMismatchedInput(e, typeNameMapper);
return jacksonErrorHelper.resolveMismatchedInput(e);
}
return Problem.builder().status(HttpStatus.BAD_REQUEST.value());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@
@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"spring.jackson.deserialization.fail-on-null-for-primitives=true"})
properties = {
"problem4j.detail-format=lowercase",
"spring.jackson.deserialization.fail-on-null-for-primitives=true"
})
class BindingPrimitiveWebFluxTest {

@Autowired private WebTestClient webTestClient;
Expand Down Expand Up @@ -136,7 +139,7 @@ void givenMalformedPrimitive_whenPost_thenReturnProblem(String path, String json
Problem expected =
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, "value")
.extension(KIND_EXTENSION, expectedKind)
.build();
Expand Down Expand Up @@ -239,7 +242,7 @@ void givenMalformedNested_whenPost_thenReturnProblem(String path, String json) {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, "nested.value")
.extension(KIND_EXTENSION, expectedKind)
.build());
Expand Down Expand Up @@ -285,7 +288,7 @@ void givenEmptyStringPrimitive_whenPost_thenReturnProblem(String path, String js
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, "value")
.extension(KIND_EXTENSION, expectedKind)
.build());
Expand Down Expand Up @@ -318,7 +321,7 @@ void givenOverflowPrimitive_whenPost_thenReturnProblem(String path, String json)
Problem expected =
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, "value")
.extension(KIND_EXTENSION, "integer")
.build();
Expand Down Expand Up @@ -347,7 +350,7 @@ void givenNullPrimitive_whenPost_thenReturnProblem() {
Problem expected =
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, "value")
.extension(KIND_EXTENSION, "integer")
.build();
Expand Down Expand Up @@ -411,7 +414,7 @@ void givenMalformedComplexObject_whenPost_thenReturnProblemWithFirstInvalidField
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(TYPE_MISMATCH_DETAIL)
.detail(TYPE_MISMATCH_DETAIL.toLowerCase())
.extension(PROPERTY_EXTENSION, expectedProperty)
.extension(KIND_EXTENSION, expectedKind)
.build()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class ErrorResponseWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class ErrorWebExceptionHandlerWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class MalformedMultipartWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class MaxUploadSizeExceededWebFluxTest {

Expand All @@ -57,7 +58,7 @@ void givenMaxUploadSizeExceeded_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.PAYLOAD_TOO_LARGE.value())
.detail(MAX_UPLOAD_SIZE_EXCEEDED_DETAIL)
.detail(MAX_UPLOAD_SIZE_EXCEEDED_DETAIL.toLowerCase())
.extension(MAX_EXTENSION, 1)
.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class MethodNotAllowedWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class MissingParameterWebFluxTest {

Expand All @@ -76,7 +77,7 @@ void givenRequestWithoutPathVariable_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_PATH_VARIABLE_DETAIL)
.detail(MISSING_PATH_VARIABLE_DETAIL.toLowerCase())
.extension(NAME_EXTENSION, "var")
.build());
});
Expand Down Expand Up @@ -112,7 +113,7 @@ void givenRequestWithoutRequestParam_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_REQUEST_PARAM_DETAIL)
.detail(MISSING_REQUEST_PARAM_DETAIL.toLowerCase())
.extension(PARAM_EXTENSION, "param")
.extension(KIND_EXTENSION, "string")
.build());
Expand Down Expand Up @@ -154,7 +155,7 @@ void givenRequestWithoutRequestPart_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_REQUEST_PART_DETAIL)
.detail(MISSING_REQUEST_PART_DETAIL.toLowerCase())
.extension(PARAM_EXTENSION, "file")
.build());
});
Expand Down Expand Up @@ -202,7 +203,7 @@ void givenRequestWithoutRequestHeader_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_HEADER_DETAIL)
.detail(MISSING_HEADER_DETAIL.toLowerCase())
.extension(HEADER_EXTENSION, "X-Custom-Header")
.build());
});
Expand Down Expand Up @@ -239,7 +240,7 @@ void givenRequestWithoutCookieValue_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_COOKIE_DETAIL)
.detail(MISSING_COOKIE_DETAIL.toLowerCase())
.extension(COOKIE_EXTENSION, "x_session")
.build());
});
Expand Down Expand Up @@ -276,7 +277,7 @@ void givenRequestWithoutRequestAttribute_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_REQUEST_ATTRIBUTE_DETAIL)
.detail(MISSING_REQUEST_ATTRIBUTE_DETAIL.toLowerCase())
.extension(ATTRIBUTE_EXTENSION, "attr")
.build());
});
Expand All @@ -297,7 +298,7 @@ void givenRequestWithoutSessionAttribute_shouldReturnProblem() {
.isEqualTo(
Problem.builder()
.status(HttpStatus.BAD_REQUEST.value())
.detail(MISSING_SESSION_ATTRIBUTE_DETAIL)
.detail(MISSING_SESSION_ATTRIBUTE_DETAIL.toLowerCase())
.extension(ATTRIBUTE_EXTENSION, "attr")
.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class NotAcceptableWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class NotFoundNoHandlerFoundWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
classes = {WebFluxTestApp.class},
properties = {
"spring.webflux.static-path-pattern=/**",
"spring.web.resources.static-locations=classpath:/static/"
"spring.web.resources.static-locations=classpath:/static/",
"problem4j.detail-format=lowercase"
},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class ProblemAdviceWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
properties = {
"problem4j.type-override=https://example.org/type/{problem.type}",
"problem4j.instance-override=https://example.org/trace/{context.traceId}",
"problem4j.tracing-header-name=X-Trace-Id"
"problem4j.tracing-header-name=X-Trace-Id",
"problem4j.detail-format=lowercase"
},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class ResponseStatusAnnotatedExceptionWebFluxTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

@SpringBootTest(
classes = {WebFluxTestApp.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"problem4j.detail-format=lowercase"})
@AutoConfigureWebTestClient
class ResponseStatusExceptionWebFluxTest {

Expand Down
Loading