Card 02/ 07

ExampleDifficulty: Intermediate1 min

A Custom Exception and Its Handler

RideNotFoundException names exactly one failure. @ExceptionHandler maps it to exactly one response, right where it's thrown.

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());
    }
}

RideNotFoundException extends RuntimeException, not Exception — unchecked, so nothing forces every caller of getRide to declare or catch it. It exists purely to be caught by name, one layer up, by the handler.