Before throwing an exception, it would be interesting to ask some questions like : Do I only need a custom error to return to the user in a specific controller or endpoint ? Or do I have to set a consistent error responses across the API with centralizing error handling ?
Depending on the need, you can add or not exception throwing. So you have two approches :
1 - Returning a ResponseEntity with an Error Code Directly (for quick responses with minimal logic): lets say all we want is returning an error because we know that the response is not the right one :
@GetMapping("/example-failure")
public ResponseEntity<String> getExampleFailure() {
//Return a response of type String instead of MyResponseType.
String response = "This is an invalid response";
return new ResponseEntity<>(response, HttpStatus.NOT_ACCEPTABLE);
}
2 - If you really need an exception handling knowing that exceptions are often reserved for truly exceptional cases or errors that need to propagate up the stack but can also be used for consistent error responses across your API.
One of the best practices for handling exceptions globally is to use @ControllerAdvice :
@GetMapping("/example-failure")
public ResponseEntity<String> getExampleFailure() {
// **Throw a new exception**
throw new InvalidResponseTypeException("Item not found")
}
...
// Here The GlobalExceptionHandler declared in the controller advice class, catches the thrown exception and responds with a consistent error
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(InvalidResponseTypeException.class)
public ResponseEntity<ErrorResponse> handleNotFoundException(InvalidResponseTypeException ex) {
ErrorResponse error = new ErrorResponse("NOT_ACCEPTABLE", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_ACCEPTABLE);
}
// You can also have in the same class other exception handlers...
}