MoreExtra· 40 min read

Error Handling

When something goes wrong, send the client a clear error and the right status code instead of an ugly stack trace.

What you will learn

  • Return the correct HTTP status
  • Throw a clean “not found” error
  • Handle errors in one central place

Errors should be helpful

If a client asks for a product that does not exist, returning null or a huge Java error is confusing. A good API returns a clear status code and a short message. The status code tells the client what kind of problem it was.

StatusMeans
200 OKSuccess
201 CreatedA new item was created
400 Bad RequestThe client sent invalid data
404 Not FoundThe thing does not exist
500 Server ErrorSomething broke on the server

Throw a clean 404

Make a small exception class and tell Spring which status it maps to with @ResponseStatus:

Throwing a 404 when a record is missing
@ResponseStatus(HttpStatus.NOT_FOUND)   // -> 404
public class NotFoundException extends RuntimeException {
    public NotFoundException(String message) {
        super(message);
    }
}

@GetMapping("/products/{id}")
public Product one(@PathVariable Long id) {
    return repo.findById(id)
        .orElseThrow(() -> new NotFoundException("No product with id " + id));
}

Note: Output: GET /products/999 (no such product) -> 404 Not Found {"status":404,"error":"No product with id 999", ...} Instead of a crash or a null, the client gets a clean 404 with your message. The status code makes the problem obvious.

Handle errors in one place

For app-wide handling, a @RestControllerAdvice class catches exceptions from all controllers, so you write the handling once:

One central handler for an exception type
@RestControllerAdvice
public class ErrorHandler {

    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Map<String, String> handleNotFound(NotFoundException ex) {
        return Map.of("error", ex.getMessage());
    }
}

Note: Output: Any NotFoundException, from any controller: -> 404 Not Found {"error":"No product with id 999"} You wrote the handling once and every controller now returns the same tidy error shape.

Tip: Pick the status that matches the problem: 404 for “not found”, 400 for “bad input”, 201 for “created”. Correct status codes make your API easy and predictable to use.

Watch out: Never send raw Java stack traces to clients — they are confusing and can leak internal details. Catch errors and return a short, friendly message with the right status instead.

Q. Which status code best fits “you asked for an item that does not exist”?

Answer: 404 Not Found means the requested resource does not exist. 400 is for invalid input, and 201 signals a successful creation.

✍️ Practice

  1. Throw a 404 NotFoundException when a Book id is missing.
  2. Add a @RestControllerAdvice handler that returns a JSON error message for it.

🏠 Homework

  1. Add proper error handling to your Task CRUD API: 404 for a missing task, with a central handler returning a clean message.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →