# 1. The mental model: RFC 9457 and Spring's four types [Index](../README.md) · Next: [2. Choosing a mechanism →](02-choosing-a-mechanism.md) ## What RFC 9457 actually specifies A problem document is a JSON (or XML) object served as `application/problem+json` (`application/problem+xml`) with five optional members: | Member | Meaning | |---|---| | `type` | a URI identifying the *kind* of problem. When absent it is assumed to be `about:blank` | | `title` | a short, human-readable summary of that kind - the same for every occurrence | | `status` | the HTTP status, repeated for convenience | | `detail` | a human-readable explanation of *this* occurrence | | `instance` | a URI identifying this occurrence | Anything else is an *extension member* - `orderId`, `errors`, `errorId` in this project. RFC 9457 obsoletes RFC 7807. The wire format did not change. What it added: a registry of common problem type URIs, guidance on multiple problems ("the most relevant or urgent problem" should be represented), and guidance for `type` URIs that cannot be dereferenced. The XML namespace is still `urn:ietf:rfc:7807` - you will see it in [`content-negotiation.txt`](output/content-negotiation.txt). ## Spring's four types | Type | What it is | Used here | |---|---|---| | `ProblemDetail` | the body: the five members plus a `properties` map for extensions | every handler | | `ErrorResponse` | an interface: "I know my status, headers and `ProblemDetail`" | all Spring MVC exceptions implement it | | `ErrorResponseException` | a convenient base class implementing `ErrorResponse` | [`OutOfStockException`](../src/main/java/com/ankurm/problems/domain/OutOfStockException.java) | | `ResponseEntityExceptionHandler` | a `@ControllerAdvice` base class that renders every Spring MVC exception as a problem | [`GlobalExceptionHandler`](../src/main/java/com/ankurm/problems/advice/GlobalExceptionHandler.java) | ## Who renders what There are three places an error body can come from, and most confusion comes from not knowing which one produced the response you are looking at: 1. **An `@ExceptionHandler`** - inside the `DispatcherServlet`, for exceptions thrown by handler methods (and Spring MVC's own exceptions). 2. **The container's error page** - Tomcat forwards to `/error`, Spring Boot's `BasicErrorController` renders `{"timestamp","status","error","path"}`. Everything the first place did not handle ends up here, including exceptions from servlet filters. 3. **Code that writes the response directly** - Spring Security's entry point and access-denied handler, or your own filters. The five setups in [chapter 2](02-choosing-a-mechanism.md) differ only in which of these three places produce `application/problem+json`.