ControllerAdvice isn't picking IllegalArgumentException thrown by an incorrect UUID value passed as @RequestParam

こ雲淡風輕ζ 提交于 2021-01-29 07:33:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!