Reputation: 865
Is it possible to catch all thrown exceptions of a particular type, say IllegalArgumentException, throughout the entire Spring Boot application and handle it one place? I want to introduce some additional logging for particular types of exception in application and I am looking for a way to avoid duplicating logic or method calls throughout the application?
Upvotes: 1
Views: 1865
Reputation: 1460
Take a look at the annotation @ExceptionHandler(value=YourException.class) and @ControllerAdvice it allows you to handle custom exceptions. The Controller Advice class can handle the exception globally. We can define any Exception Handler methods in this class file.
@ControllerAdvice
public class ProductExceptionController {
@ExceptionHandler(value = ProductNotfoundException.class)
public ResponseEntity<Object> exception(ProductNotfoundException exception) {
return new ResponseEntity<>("Product not found", HttpStatus.NOT_FOUND);
}
}
Upvotes: 5
Reputation: 6216
Springboot provides us with the capability to handle exceptions globally using the @ControllerAdvice
annotation . So, instead of handling exceptions and logging it in each controller, you could actually throw the exception from every controller and handle it in a single place like :
BusinessException extends RunTimeException {
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value
= { BusinessException.class,IllegalArgumentException.class})
protected ResponseEntity<Object> handleCustomException(
RuntimeException ex, WebRequest request) {
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.NOTFOUND, request);
}
}
In your case, you could create a custom exception class and throw your custom exception from where ever your custom logic is needed. So, your could then handle this custom exception globally to provide your logic. This is one way to handle exceptions globally without duplicating logic. You could also do this using spring aop using pointcut.
@Aspect
public class LoggingAspect {
@AfterThrowing (pointcut = "execution(* com.yourservice.yourpackage.*(..))", throwing = "ex")
public void logAfterThrowingAllMethods(Exception ex) throws Throwable
{
System.out.println("****LoggingAspect.logAfterThrowingAllMethods() " + ex);
}
}
Just add spring aop
and aspectJ
as dependencies for this approach.
Upvotes: 1
Reputation: 7131
Spring AOP can be used to address this cross cutting concern.
@AfterThrowing advice can be used for this purpose.
The name used in the throwing attribute must correspond to the name of a parameter in the advice method. When a method execution exits by throwing an exception, the exception is passed to the advice method as the corresponding argument value. A throwing clause also restricts matching to only those method executions that throw an exception of the specified type
Example can be found here
Upvotes: 1