Card 02/ 07

ExampleDifficulty: Intermediate1 min

Error Handling Example: A Custom Exception and Its Handler

One exception names one failure, and one handler method turns it into one 404 response.

A custom exception names one specific failure, and an @ExceptionHandler method, which Spring calls whenever that exception is thrown, turns it into one specific response. Here the failure is a ride that does not exist, and the response is 404 Not Found with a message.

RideNotFoundException is thrown by the controller when a ride is missing, and a handler method in the same controller catches it by type:

java
class RideNotFoundException extends RuntimeException {
    RideNotFoundException(String message) { super(message); }
}

@RestController
class RideController {

    @GetMapping("/rides/{id}")
    Ride getRide(@PathVariable String id) {
        throw new RideNotFoundException("Ride not found with id: " + id);
    }

    @ExceptionHandler(RideNotFoundException.class)
    ResponseEntity<String> handleNotFound(RideNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}

When getRide throws, Spring looks for an @ExceptionHandler whose type matches the exception, calls handleNotFound, and sends what it returns: status 404, and the exception's message as the body. The controller method itself contains no error-handling code at all.

RideNotFoundException extends RuntimeException, not Exception, which makes it unchecked: Java does not force every caller of getRide to declare or catch it. That is what you want for a failure whose only job is to travel up to a handler that knows what to do with it.

So a controller method can stay focused on the successful case and throw when something is wrong; the handler owns the translation into HTTP.