🔸 TLDR
▪️ Use ProblemDetail to return consistent, machine-readable errors (status + title + detail + type + extra fields) ✅

🔸 CONTEXT
▪️ APIs often return random error shapes: sometimes {message}, sometimes {error}, sometimes HTML 😅
▪️ Clients hate guessing. Observability hates inconsistency.
▪️ ProblemDetail gives you a standard error contract (Problem Details for HTTP APIs — RFC 9457).
🔸 Snippet: custom 404 (ProblemDetail + @RestControllerAdvice)
@RestControllerAdvice class ApiErrors { @ExceptionHandler(CustomerNotFoundException.class) ProblemDetail handle(CustomerNotFoundException ex) { ProblemDetail pd = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage()); pd.setTitle("Customer not found"); pd.setType(URI.create("https://lnkd.in/evfJ_kGK")); pd.setProperty("customerId", ex.customerId()); // 👈 custom field pd.setProperty("traceId", TraceId.current()); // 👈 correlation id (example) return pd; } }
🔸 Snippet: validation errors (return a list of field issues)
@RestControllerAdvice class ValidationErrors { record FieldIssue(String field, String message) {} @ExceptionHandler(MethodArgumentNotValidException.class) ProblemDetail handle(MethodArgumentNotValidException ex) { ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST); pd.setTitle("Validation failed"); pd.setType(URI.create("https://lnkd.in/ehDs73e5")); List<FieldIssue> issues = ex.getBindingResult().getFieldErrors().stream() .map(fe -> new FieldIssue(fe.getField(), msg(fe))) .toList(); pd.setProperty("errors", issues); return pd; } private String msg(FieldError fe) { return fe.getDefaultMessage() != null ? fe.getDefaultMessage() : "Invalid value"; } }
🔸 Takeaways
▪️ Standardize your error shape → clients stop “parsing strings” 🧠
▪️ Set type to a stable doc URL → self-explaining API 🔗
▪️ Add safe custom fields via setProperty(...) (traceId, errorCode, errors[]) 🧾
▪️ Don’t leak internals (stacktraces / SQL / secrets) 🔒
▪️ Centralize with @RestControllerAdvice for consistency ⚙️
#SpringBoot #SpringFramework #Java #API #REST #ErrorHandling #ProblemDetail
🍃📗 Grab your Spring cert Book: https://bit.ly/springtify