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.
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: