stackUser
stackUser

Reputation: 579

Global exception handling (non REST controller code)

I was trying to handle global exception but its not working without method call from REST API.

I have following code

@SpringBootApplication 
public class LogReduceDemoApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(LogReduceDemoApplication.class, args);
        System.out.println(".......Started......");
        LogReduceDemoApplication.testException();
    }

    public static void testException() throws Exception {
        throw new Exception("testException...");
    }
}

Exception Handler

@ControllerAdvice
public class ExceptionHelper {

    static final Logger logger = LoggerFactory.getLogger(ExceptionHelper.class.getName());

    @ExceptionHandler(value = { NullPointerException.class,Exception.class })
    public ResponseEntity<Object> handleException(Exception ex) {
        System.out.println("Inside handleException...");
        String msg="ex="+ex+", ex.getMessage()="+ex.getMessage();
        System.out.println("Exception Msg: "+ msg);
        return new ResponseEntity<Object>(msg, HttpStatus.BAD_REQUEST);
    }
}

When I am calling LogReduceDemoApplication.testException() method from REST controller then it is triggering exception handler. But when there is a call to the same method using main() function its not triggering Exception handler instead it is printing all exception details.

How to use exception handler for the method call from main function(not from REST controller)?

Upvotes: 2

Views: 4360

Answers (2)

tuuka
tuuka

Reputation: 33

You should try to use Aspects. Something like this:

@Component
@Aspect
public class LoggingAspect {    
       
    private final Logger logger =
            LoggerFactory.getLogger(getClass().getSimpleName());               

    @Around("execution(* {YOU_PACKAGE_HERE}..*.*(..))")
    public Object someOperationAround(ProceedingJoinPoint pjp) throws Throwable {
        Object result;
        try {
            long t1 = System.currentTimeMillis();
            logger.debug("Calling {} with args: {} ",
                    pjp.getSignature().toShortString(),
                    pjp.getArgs());
            result = pjp.proceed();
            double duration = (System.currentTimeMillis() - t1) / 1000.;
            logger.debug("{} - Time elapsed: {}sec",
                    pjp.getSignature().toShortString(), duration);
        } catch (Throwable ex) {
            logger.warn("When call {} with args: {} Exception thrown: {}",
                    pjp.getSignature().toShortString(),
                    pjp.getArgs(), ex.getMessage());
            throw ex;
        }
        return result;
    }

}

Or @AfterThrowing instead of @Around if you need to catch only exceptions.

    @AfterThrowing(pointcut="execution(* {YOU_PACKAGE_HERE}..*.*(..)))", throwing="theExc")
    public void afterThrowingAdvice(JoinPoint theJoinPoint, Throwable theExc) {

        String method = theJoinPoint.getSignature().toShortString();
        System.out.println("\n=====>>> Executing @AfterThrowing on method: " + method);
    
        // log the exception
        System.out.println("\n=====>>> The exception is: " + theExc);    
    }

Upvotes: 3

EricSchaefer
EricSchaefer

Reputation: 26330

You can't. It also does not make sense. The @ExceptionHandler method is returning a ResponseEntity that does not make sense outside the REST context.

Upvotes: 0

Related Questions