Skip to content
Advertisement

How to catch non-MVC and non-REST exceptions in Spring Boot

I’ve been able to find endless amounts of tutorials on how to catch unhandled exceptions in Spring MVC or Spring REST, but what I want to know is how to catch unhandled exceptions without using the Spring Web framework at all.

I am writing an application which does not have a web component, and I am not going to import Spring Web only for exception handling.

When a @Service throws an exception that goes unhandled, I need to catch it so that I can log it properly to Raygun.

For example, consider this method in a Service that purposely throws an uncaught exception:

@Scheduled(fixedDelay = 100)
public void doSomething() {
    throw new RuntimeException("Uh oh!");
}

Its output will be:

2017-08-16 00:19:40.202 ERROR 91168 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

java.lang.RuntimeException: Uh oh!
    at com.mitchtalmadge.example.ExampleService.doSomething(ClassSyncService.java:48) ~[classes/:na]
    at com.mitchtalmadge.example.ExampleService$$FastClassBySpringCGLIB$$1dd464d8.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
    ...

How do I catch that?

Is there no easy way to do this?

Advertisement

Answer

You can define an aspect. Using Java-based configuration it will look like this:

@Aspect
public class ExceptionHandler {

    @AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
    public void handleError(Exception ex) {
        //handling the exception
     }
}

If you need to inject a bean, add the @Component annotation:

@Aspect
@Component
public class ExceptionHandler {

    @Autowired
    private NotificationService notificationService;

    @AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
    public void handleError(Exception ex) {
        notificationService.sendMessage(ex.getMessage());
     }
}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement