Lesson 35 / 38
API Status Codes & Error Handling
Return the right HTTP status for every outcome and centralise error responses with a global @ExceptionHandler instead of scattering try/catch across controllers.
Status codes are part of the contract
200 OK, 201 Created, 204 No Content for success; 400 Bad Request (malformed input), 401 Unauthorized (no/bad credentials), 403 Forbidden (authenticated but not allowed), 404 Not Found, 409 Conflict (duplicate/version clash) for client errors; 500 Internal Server Error for unexpected server failures.
A global exception handler
@RestControllerAdvice centralises exception-to-response mapping across every controller — no controller needs a try/catch for expected failures like a missing resource.
@RestControllerAdvice
class ApiExceptionHandler {
@ExceptionHandler(OrderNotFoundException.class)
ResponseEntity<ErrorBody> notFound(OrderNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorBody("ORDER_NOT_FOUND", e.getMessage()));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
ResponseEntity<ErrorBody> badInput(MethodArgumentNotValidException e) {
return ResponseEntity.badRequest()
.body(new ErrorBody("VALIDATION_ERROR", e.getMessage()));
}
}Status code check
Quick check: A client sends valid credentials but tries to delete another user's order. What status code fits best?
- 401 Unauthorized
- 404 Not Found
- 403 Forbidden
- 500 Internal Server Error
Answer
403 Forbidden — 401 means missing/invalid credentials; here the client is authenticated but not allowed to act on this resource — that's 403.