Card 03/ 07

ExampleDifficulty: Intermediate1 min

Error Handling Example: One @RestControllerAdvice for Every Controller

The same handler, written once, answers the same exception from two unrelated controllers.

@RestControllerAdvice marks a class whose @ExceptionHandler methods, the methods Spring calls when a given exception is thrown, apply to every controller in the application. An @ExceptionHandler inside one controller only catches exceptions thrown by that controller, so moving it into an advice class is how one handler serves them all.

A handler for RideNotFoundException that answers 404, in a class of its own:

java
@RestControllerAdvice
class GlobalExceptionHandler {
    @ExceptionHandler(RideNotFoundException.class)
    ResponseEntity<String> handleNotFound(RideNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("centralized: " + ex.getMessage());
    }
}

Two separate controllers, RideLookupController and DriverLookupController, each throw RideNotFoundException, each with its own message, and contain no handler of their own. In a real API that shared exception would get a general name such as NotFoundException. Calling each one:

text
GET /rides/1   -> 404 centralized: Ride not found with id: 1
GET /drivers/2 -> 404 centralized: Driver not found with id: 2
run in a container: two separate controllers, one handler, both throwing the same exception

Both answers came from the one handler, which the centralized: prefix shows. The two controllers share nothing except the exception type they throw.

So the error format of the whole API lives in one class. Changing it, or adding a handler for a new kind of failure, is one edit that every controller picks up.