Spring Boot Tutorial 0/110 lessons ~6 min read Lesson 21
Exception Handling
Centralised exception handling turns scattered try/catch into a single, consistent error contract.
Course progress0%
Focus
3 guided sections
Practice signal
Examples included
Career prep
Foundation builder
Introduction
Centralised exception handling turns scattered try/catch into a single, consistent error contract. Pair @ControllerAdvice with custom domain exceptions and you'll never write a try/catch in a controller again.
Informative example
ts
// Domain exceptionpublic class NotFoundException extends RuntimeException {public NotFoundException(String msg) { super(msg); }}// Global handler@RestControllerAdvicepublic class ApiExceptionHandler {record ApiError(String code, String message, Instant timestamp) {}@ExceptionHandler(NotFoundException.class)public ResponseEntity<ApiError> notFound(NotFoundException ex) {return ResponseEntity.status(404).body(new ApiError("not_found", ex.getMessage(), Instant.now()));}@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<ApiError> validation(MethodArgumentNotValidException ex) {String msg = ex.getBindingResult().getFieldErrors().stream().map(e -> e.getField() + ": " + e.getDefaultMessage()).collect(Collectors.joining("; "));return ResponseEntity.badRequest().body(new ApiError("validation_error", msg, Instant.now()));}@ExceptionHandler(Exception.class)public ResponseEntity<ApiError> fallback(Exception ex) {log.error("Unhandled", ex);return ResponseEntity.status(500).body(new ApiError("internal_error", "Something went wrong", Instant.now()));}}
Best practices
- Define a single error envelope shape for the whole API (RFC 7807 Problem JSON is great).
- Map domain exceptions to HTTP status; never leak stack traces to clients.
- Log full context server-side with a trace ID, return a short user message.
Ready to mark this lesson complete?Track your journey across the entire course.