问题
I have the following controller:
@Slf4j
@RestController
@RequestMapping("/v1")
@Validated
public class HighlightController {
// ...
@GetMapping("/highlights")
public ResponseEntity<List<Highlight>> getHighlights(
@RequestParam(required = false) UUID impersonateUserId
) {
// ...
Then I have the following controller exception handler:
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
//...
@ExceptionHandler(value = IllegalArgumentException.class)
public ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException ex) {
log.info("Handled: IllegalArgumentException", ex);
return buildResponseEntity(new ApiErrorResponse(
HttpStatus.BAD_REQUEST,
"Incorrect Request",
ex
));
}
@ExceptionHandler(value = RuntimeException.class)
public ResponseEntity<Object> handleRuntimeException(RuntimeException ex) {
log.error("Handled: Runtime exception", ex);
return buildResponseEntity(new ApiErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR,
"Internal error",
ex
));
}
//...
private ResponseEntity<Object> buildResponseEntity(ApiErrorResponse errorResponse) {
return new ResponseEntity<>(errorResponse, errorResponse.getStatus());
}
When I send a request to v1/highlights
endpoint with an incorrect UUID valie, I would expect that the IllegalArgumentException
thrown by StringToUUIDConverter
when parsing UUID from String value would be caught by handleIllegalArgumentException
, but instead, it is handled by handleRuntimeException
. Why is that?
回答1:
If you call your controller, for example like:
http://localhost:8080/v1/highligths?impersonateUserId=x
what would be the result? For me it is not IllegalArgumentException
.
Have a look what I got:
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: Invalid UUID string: x org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: Invalid UUID string: x
So could it be that you should handle MethodArgumentTypeMismatchException
?
I admit it is a bit confusing that the first lines suggest the cause to be IllegalArguemntException
.
If I call:
localhost:8080/v1/highligths?impersonateUserId=123e4567-e89b-12d3-a456-556642440000
everything seems to be ok.
If I then call:
http://localhost:8080/v1/highligths?impersonateUserId=123e4567-e89b-12d3-a456-556642440000x
I get:
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: UUID string too large org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.UUID'; nested exception is java.lang.IllegalArgumentException: UUID string too large
But again, the exception thrown is actually:
MethodArgumentTypeMismatchException
来源:https://stackoverflow.com/questions/63969454/controlleradvice-isnt-picking-illegalargumentexception-thrown-by-an-incorrect-u