Step 06 — Exception handling RFC 7807¶
Obiettivo: errori standardizzati, interoperabili, leggibili.
Perché RFC 7807¶
ProblemDetail è uno standard IETF per rappresentare errori HTTP. Vantaggi:
- Stesso formato in tutti i client (SDK, frontend).
- Estendibile: si possono aggiungere campi custom senza rompere la spec.
- Spring 6+ lo supporta nativamente.
Esempio di errore¶
HTTP/1.1 404 Not Found
Content-Type: application/problem+json
{
"type": "https://federicocalo.dev/errors/not-found",
"title": "Resource not found",
"status": 404,
"detail": "Project with id '9b1f...' not found",
"resourceType": "Project",
"identifier": "9b1f...",
"timestamp": "2026-05-20T18:25:43Z"
}
Implementazione¶
GlobalExceptionHandler.java (estratto)
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
ProblemDetail p = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
p.setType(URI.create("https://federicocalo.dev/errors/not-found"));
p.setTitle("Resource not found");
p.setProperty("resourceType", ex.getResourceType());
p.setProperty("identifier", ex.getIdentifier());
p.setProperty("timestamp", Instant.now());
return p;
}
// ... altri handler
}
Mappature¶
| Eccezione | HTTP | type |
|---|---|---|
ResourceNotFoundException | 404 | /errors/not-found |
MethodArgumentNotValidException | 400 | /errors/validation |
HttpMessageNotReadableException, MethodArgumentTypeMismatchException | 400 | /errors/bad-request |
InvalidStateTransitionException, ProjectArchivedException, DataIntegrityViolationException | 409 | /errors/conflict |
Tutte le altre Exception | 500 | /errors/internal (con log!) |
Pitfall¶
Mai serializzare lo stack trace in produzione
Configura server.error.include-stacktrace: never nel profilo prod.
Custom exception per ogni cosa
Non serve. Tre/quattro tipi di eccezione di business + il fallback generico bastano.
Esercizi¶
- Aggiungi un handler per
OptimisticLockingFailureException→ HTTP 409 con messaggio dedicato. - Includi un campo
traceIdnel ProblemDetail (preso daMDC). - Discuti vantaggi/svantaggi di esporre
typecome URL canonico (RFC 7807) vs. codice opaco.