oneCoderToRuleThemAll
oneCoderToRuleThemAll

Reputation: 865

Java/Springboot: Catch and handle a particular exception in one place?

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

Answers (3)

Edu Costa
Edu Costa

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

Ananthapadmanabhan
Ananthapadmanabhan

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

R.G
R.G

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

Related Questions