Handling exceptions in a Spring Boot application
The Spring framework offers developers several options for handling exceptions in their applications. One of them is a global exception handler with the @ControllerAdvice
and @ExceptionHandler
annotations.
With this type of exception handling, you need to write a separate class that handles all exceptions that may be thrown by the application in one central place:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception1.class)
public String handleException1() {
// handles exception type Exception1
}
@ExceptionHandler(Exception2.class)
public String handleException2() {
// handles exception type Exception2
}
// handlers for other exceptions...
}
The class is annotated with @ControllerAdvice
, which is a type of @Component
. It tells Spring to intercept all the handling methods and execute them when the corresponding exceptions are thrown. In the exception handling methods, you can log the exception, redirect to user-friendly error pages, change the response status code, and any other custom logic you want to handle when the matching exception occurs.
Example:
CityController.java
@RestController
public class CityController {
@GetMapping("/{id}")
public ResponseEntity<CityResponseDto> getById(@PathVariable Long id) throws CityNotFoundException {
throw new CityNotFoundException(id);
}
}
CityNotFoundException.java
public class CityNotFoundException extends RuntimeException {
public CityNotFoundException(Long id) {
super(String.format("City with Id %d not found", id));
}
}
ErrorDetails.java
public class ErrorDetails {
private Date time;
private String message;
//+ fields for other required data
}
GlobalExceptionHandler.java
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(CityNotFoundException.class)
public ResponseEntity<ErrorDetails> handleCityNotFoundException(CityNotFoundException exception) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), exception.getMessage());
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
}
}