Global Exceptions Handling in Spring Boot
In Spring Boot, a global exception handling mechanism allows you to catch and handle exceptions across the whole application in one central place â rather than duplicating try-catch
logic everywhere.
This is typically done using @ControllerAdvice
(or @RestControllerAdvice
for REST APIs) along with @ExceptionHandler
.
1. Why Use Global Exceptions?
- Centralized handling â all exception logic in one place.
- Cleaner controllers â no repetitive try-catch.
- Consistent responses â same error structure for all endpoints.
- Easier debugging â one spot to log errors.
2. Steps to Create Global Exception Handling in Spring Boot
Step 1: Create a Custom Error Response DTO
This ensures the API sends consistent error messages.
public class ErrorResponse {
private String message;
private String details;
private String timestamp;
public ErrorResponse(String message, String details, String timestamp) {
this.message = message;
this.details = details;
this.timestamp = timestamp;
}
// getters & setters
}
Step 2: Create a Custom Exception (Optional)
You can make your own exception type for business logic errors.
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
Step 3: Create Global Exception Handler with @ControllerAdvice
Use @RestControllerAdvice
if returning JSON responses.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.time.LocalDateTime;
@RestControllerAdvice
public class GlobalExceptionHandler {
// Handle Specific Exception
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
ex.getMessage(),
"Resource not found in the system",
LocalDateTime.now().toString()
);
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
// Handle All Other Exceptions
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {
ErrorResponse error = new ErrorResponse(
ex.getMessage(),
"Unexpected error occurred",
LocalDateTime.now().toString()
);
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Step 4: Throw Exceptions in Your Controller or Service
Instead of returning null or empty, throw the custom exception.
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable int id) {
if (id != 1) {
throw new ResourceNotFoundException("User with ID " + id + " not found");
}
return "John Doe";
}
}
3. How It Works
- If
/api/users/2
is called,ResourceNotFoundException
is thrown. -
GlobalExceptionHandler
catches it. - Sends a clean JSON error with HTTP
404 Not Found
.
Example response:
{
"message": "User with ID 2 not found",
"details": "Resource not found in the system",
"timestamp": "2025-08-12T11:30:45"
}
4. Extra Tips
- Use
@ResponseStatus
on exceptions if you want Spring to auto-set status codes. - You can handle validation errors (
MethodArgumentNotValidException
) in the same advice. - Use logging in the exception handler to debug issues.