0
0
SpringbootHow-ToBeginner · 4 min read

How to Use ProblemDetail in Spring Boot for Error Handling

In Spring Boot, ProblemDetail is used to create standardized error responses following RFC 7807. You create a ProblemDetail instance with status, detail, and type, then return it from your controller or exception handler to provide clear error information.
📐

Syntax

The ProblemDetail class in Spring Boot represents a standardized error response. You create it using ProblemDetail.forStatus(HttpStatus) or ProblemDetail.forStatusAndDetail(HttpStatus, String). You can set properties like title, detail, type, and instance to describe the error.

Return the ProblemDetail object from a controller method or an exception handler annotated with @ExceptionHandler.

java
ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.NOT_FOUND);
problem.setTitle("Resource Not Found");
problem.setDetail("The requested resource was not found on the server.");
problem.setType(URI.create("https://example.com/probs/not-found"));
return problem;
💻

Example

This example shows how to use ProblemDetail in a Spring Boot REST controller to return a 404 error with a detailed message when a resource is not found.

java
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import java.net.URI;

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public String getUser(@PathVariable String id) {
        if (!"123".equals(id)) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
        }
        return "User 123 details";
    }

    @ExceptionHandler(ResponseStatusException.class)
    public ProblemDetail handleNotFound(ResponseStatusException ex) {
        ProblemDetail problem = ProblemDetail.forStatusAndDetail(ex.getStatusCode(), ex.getReason());
        problem.setTitle("User Retrieval Error");
        problem.setType(URI.create("https://example.com/probs/user-not-found"));
        return problem;
    }
}
Output
HTTP/1.1 404 Not Found Content-Type: application/problem+json { "type": "https://example.com/probs/user-not-found", "title": "User Retrieval Error", "status": 404, "detail": "User not found" }
⚠️

Common Pitfalls

  • Not setting the Content-Type header to application/problem+json can cause clients to misinterpret the response.
  • Returning plain strings or custom objects instead of ProblemDetail loses the benefit of standardized error format.
  • Forgetting to set meaningful type URIs makes it harder for clients to understand error categories.
java
/* Wrong way: returning plain string */
@GetMapping("/wrong/{id}")
public String wrongHandler(@PathVariable String id) {
    return "User not found"; // No status or structured error
}

/* Right way: returning ProblemDetail */
@GetMapping("/right/{id}")
public ProblemDetail rightHandler(@PathVariable String id) {
    ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.NOT_FOUND);
    problem.setTitle("User Not Found");
    problem.setDetail("No user with id " + id);
    problem.setType(URI.create("https://example.com/probs/user-not-found"));
    return problem;
}
📊

Quick Reference

Method/PropertyDescription
ProblemDetail.forStatus(HttpStatus)Creates a ProblemDetail with the given HTTP status.
ProblemDetail.forStatusAndDetail(HttpStatus, String)Creates a ProblemDetail with status and detail message.
setTitle(String)Sets a short, human-readable summary of the problem.
setDetail(String)Sets a detailed explanation of the problem.
setType(URI)Sets a URI identifying the problem type.
setInstance(URI)Sets a URI identifying the specific occurrence of the problem.

Key Takeaways

Use ProblemDetail to return standardized error responses in Spring Boot following RFC 7807.
Create ProblemDetail with status and detail, then set title and type for clarity.
Return ProblemDetail from controller methods or exception handlers for consistent error handling.
Always set the Content-Type to application/problem+json for proper client interpretation.
Avoid returning plain strings or custom objects for errors to keep responses standardized.