Error handling
On this page 8 topics
Overview
Topics
- Custom exceptions
- @ControllerAdvice
- consistent API error responses
Learn first
2 h of practice (estimate)
Learning outcomes
- Design a small exception hierarchy for an application (not found, conflict, business rule).
- Map exceptions to HTTP responses centrally with
@RestControllerAdvice. - Return consistent error bodies using RFC 9457 Problem Details (
ProblemDetail). - Avoid leaking stack traces or internals to clients while logging them server-side.
Lessons
Lab and exercises
Lab
JNR-015-LAB1 · Consistent errors
Outcomes: 1–4 · Time: ~2 h
- Create
ShopExceptionwithNotFoundException,ConflictException,BusinessRuleException. - Write
@RestControllerAdvicemapping: validation to 400 (with aerrorslist of field and message), not found to 404, conflict (duplicate SKU) to 409, anything else to 500. - Make all bodies
ProblemDetail. - Log unexpected exceptions server-side; return a generic message.
- Document the single error shape in the README.
Acceptance: every error matches one documented shape; no stack trace or internal message appears in any response.
Exercises (assessment: error-contract review)
| ID | Outcome | Task |
|---|---|---|
| JNR-015-EX01 | 1 | Draw the hierarchy for Shop: base, not found, conflict, business rule; state who throws each. |
| JNR-015-EX02 | 2 | Remove try/catch from a given controller and add the equivalent handler. |
| JNR-015-EX03 | 3 | Return a ProblemDetail for a 409 duplicate SKU, with a custom sku property. |
| JNR-015-EX04 | 4 | Review a response containing org.postgresql... duplicate key text; rewrite the handler. |
| JNR-015-EX05 | 3 | Review an error contract: a 200 with "error": true, three error shapes, one exposed stack trace; list fixes. |
Show solutions
- EX01
ShopException(base) withNotFoundException(repositories/services),ConflictException(services on duplicates),BusinessRuleException(domain rules). - EX02
@ExceptionHandler(NotFoundException.class)returningProblemDetail.forStatusAndDetail(NOT_FOUND, ex.getMessage()). - EX03
var pd = ProblemDetail.forStatusAndDetail(CONFLICT, "SKU exists"); pd.setProperty("sku", sku); return pd; - EX04 Log the original exception; return
ProblemDetail409 or 500 with a safe message. - EX05 Use proper status codes; one shape (
ProblemDetail); hide traces and log them. - Outcome 3 is also covered by the lab and quiz.
Quiz
Outcomes: O1 exception hierarchy · O2 central mapping · O3 Problem Details · O4 no leaks.
A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.
Practical part
Five exercises JNR-015-EX01 to EX05 plus the lab. The assessment is the error-contract review (EX05). Pass: quiz at least 8/10, EX05 finds all three flaws, lab acceptance met.
Common mistakes
Try/catch in every controller; 200 with "error": true; exposing exception messages from the database.
Assessment
Error-contract review.
Career relevance
API conventions (JNR-020) and incident diagnosis.