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?
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());
}
}
You can use the aop in spirngframework,first you should config the aop configuration.
<bean id="aspect" class="com.zhuyiren.Main"/>
<aop:config>
<aop:aspect ref="aspect">
<aop:after-throwing method="after" throwing="ex" pointcut="execution(* com.zhuyiren.service..*.*(..)),args(ex)"/>
</aop:aspect>
</aop:config>
and then you should declare a aspect
class has method be named after
:
public class Main {
public void after(JoinPoint point,Throwable ex){
System.out.println(point);
System.out.println("catch error:"+ex.getMessage());
}
When the service is throwning a error,the method will catch and resolve it. In my Sevice,i make a ArithmeticException,and run the application,the print is:
execution(TeacherInfo com.zhuyiren.service.TeacherService.getTeacherInfo())
catch error:/ by zero
Of course,the above configuration is depends on xml,you also can do it through Annotation
such as @Aspect
,@Pointcut
,@AfterThrowing
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With