-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
Describe the bug
If the rest-client you are calling uses JsonInclude.Include.ALWAYS so that it for example responds with:
{
"status": 401,
"detail": null,
"title": "The JWT has expired",
"type": null,
"instance": "test/get"
}
Then you will get a null pointer exception since uriOrThrow() will still be called since the key is present. Same is true for instance
To Reproduce
This code reproduces the error:
public class DemoResource {
@Inject
ObjectMapper objectMapper;
@GET
@Path("/test-object-mapper")
public void objectMapper() {
String json = """
{
"status": 401,
"detail": null,
"title": "The JWT has expired",
"type": null,
"instance": "test/get"
}
""";
try {
objectMapper.readValue(json, HttpProblem.class);
}catch (JsonProcessingException e) {
throw new RuntimeException("Failed to deserialize JSON to HttpProblem", e);
}
}
}
@QuarkusTest
class RestClientIT {
static {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
}
@Test
void objectMapper() {
given()
.accept(ContentType.JSON)
.get("/test-object-mapper")
.then()
.statusCode(500);
}
}
Expected behavior
I expect the object mapper to skip these properties when their key is present but the value is null aka something like this:
Object child = rawDeserializedProblem.get(fieldName);
if (child == null) {
// Ignore null values
continue;
}
switch (fieldName) {
case "type" -> builder.withType(uriOrThrow(child, fieldName, jsonParser));
case "status" -> builder.withStatus(intOrThrow(child, fieldName, jsonParser));
case "title" -> builder.withTitle((String) child);
case "detail" -> builder.withDetail((String) child);
case "instance" -> builder.withInstance(uriOrThrow(child, fieldName, jsonParser));
default -> builder.with(fieldName, child);
}
Metadata
Metadata
Assignees
Labels
No labels