One place decides the shape of every error, instead of try/catch scattered through controllers.
@RestControllerAdvice
class ApiExceptionHandler {
@ExceptionHandler(NoSuchElementException.class)
ResponseEntity<ApiError> notFound(NoSuchElementException e) {
return ResponseEntity.status(404).body(new ApiError("NOT_FOUND", e.getMessage()));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
ResponseEntity<ApiError> invalid(MethodArgumentNotValidException e) {
return ResponseEntity.badRequest().body(new ApiError("INVALID", e.getMessage()));
}
}
Every endpoint now returns the same JSON error shape,
and controllers contain no error-handling code at all.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-11