Errors with @RestControllerAdvice
Turn exceptions into consistent, standard JSON error responses in one place.
Open this lesson in the learning hubKey points
- Throw meaningful exceptions from services. Do not return null or error codes.
@RestControllerAdviceholds@ExceptionHandlermethods that apply across every controller.- Spring 6 ships
ProblemDetail, the RFC 9457 error format: type, title, status, detail. - Never leak a stack trace or SQL text to the client. Log the full detail, return a clean message.
- Extend
ResponseEntityExceptionHandlerto also reshape Spring's built-in errors, like validation failures. - Match the status to the cause: 400 bad input, 404 missing, 409 conflict, 500 only for genuine bugs.
Example
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
@RestControllerAdvice
public class ApiExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(ApiExceptionHandler.class);
@ExceptionHandler(OrderNotFoundException.class)
ProblemDetail notFound(OrderNotFoundException ex) {
ProblemDetail pd = ProblemDetail.forStatusAndDetail(
HttpStatus.NOT_FOUND, ex.getMessage());
pd.setTitle("Order not found");
pd.setType(URI.create("https://api.example.com/errors/order-not-found"));
return pd; // 404 + application/problem+json
}
@ExceptionHandler(InsufficientStockException.class)
ProblemDetail conflict(InsufficientStockException ex) {
ProblemDetail pd = ProblemDetail.forStatusAndDetail(
HttpStatus.CONFLICT, "Not enough stock for " + ex.sku());
pd.setProperty("sku", ex.sku()); // extra fields are allowed
return pd;
}
@ExceptionHandler(Exception.class)
ProblemDetail unexpected(Exception ex) {
log.error("Unhandled error", ex); // full detail to the log
return ProblemDetail.forStatusAndDetail(
HttpStatus.INTERNAL_SERVER_ERROR, "Something went wrong");
}
}
One advice class gives your whole API a single, predictable error shape.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Boot course, and every lesson in it is listed on the Spring Boot contents page.