Spring Boot - @ControllerAdvice: Global ExceptionHandler not working

ProbabilisticCode :

Situation

I have implemented a global exception handler, namely CustomResponseEntityExceptionHandler.java as follows:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Exception.class)
    public final ResponseEntity<ExceptionResponse> handleAllExceptions(Exception ex, WebRequest request) {
        return new ResponseEntity<>(new ExceptionResponse(ex.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(EntityNotFoundException.class)
    public final ResponseEntity<ExceptionResponse> handleEntityNotFoundException(Exception ex, WebRequest request) {
        return new ResponseEntity<>(new ExceptionResponse(ex.getMessage()), HttpStatus.NOT_FOUND);
    }
}

As you can see, there are two handler methods:

  • One for any Exception (Exception.class)
  • One for my custom defined ExceptionResponse.java class

In my @RestController class I hardcoded a throw new EntityNotFoundException():

@RestController
@RequestMapping("/admin/challenge")
public class AdminChallengeController {
@GetMapping("/{id}")
    public Challenge findById(@PathVariable Long id) {
        throw new EntityNotFoundException("hardcoded message");
}

// other class members

Problem

When making a request to "/admin/challenge/1" the @ControllerAdvice never gets executed. I tested this by putting in a hardcoded message into the @ControllerAdvice class (NOT the Controller itself as above), and after this, the message from the Controller is returned in the response, NOT the @ControllerAdvice string. Also, even though I should be getting a 404 error, I still get a 500 error.

Can anyone help me?

Update

As answered by the accepted post, the problem was the lack of getters and setters to the respective fields inside the ExceptionResponse.java class.

Kenan Güler :

Your code looks ok. In such cases debugging would really help. You can try to set a breakpoint for the following part:

return new ResponseEntity<>(new ExceptionResponse(ex.getMessage()), HttpStatus.NOT_FOUND);

You will see that the EntityNotFoundException is actually caught there. The problem is probably the custom ExceptionResponse that you created, which Spring doesn't know how to convert it. Did you create getters and setters within the ExceptionResponse class? e.g.

// or just use the annotations below if you use lombok
// @AllArgsConstructor
// @Data
public class ExceptionResponse {
    String message;

    public ExceptionResponse(String message) { ... }

    public String getMessage() { ... }

    public void setMessage(String message) { ... }
}

I would also recommend to use gson as preferred json mapper for the HTTP message conversion, unless you use Jackson or have implemented a custom body writer yourself:

application.properties:

spring.http.converters.preferred-json-mapper=gson

or using application.yml:

spring:
    # other settings ...
    http:
        converters:
            preferred-json-mapper: gson

Links:

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=400346&siteId=1