Generic exception handler for @Scheduled tasks in Spring (Boot) with Java configuration

I have many scheduled tasks in my Spring Boot application (ver 1.4.2) and you want to catch all exceptions from them using a single handler, as is possible for regular controllers with @ExceptionHandler annotation. This approach does not work for tasks identified using @Scheduled annotations due to streaming:

@Component public class UpdateJob { @Transactional @Scheduled(cron = "0 1 0 * * *") public void runUpdateUsers() { userService.updateUsers(); } @ExceptionHandler public void handle(Exception e) { // some more logic here logger.error(e.getMessage()); } } 

@ExceptionHandler does not work for the @Scheduled method (and it turns out that it is not intended). Instead, Spring Boot uses its LoggingErrorHandler :

 2016-12-08 15:49:20.016 ERROR 23119 --- [pool-7-thread-1] osssTaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task. 

Is there any way to replace or provide a default exception handler for scheduled tasks? Or would it be advisable (and possible) to switch to the PropagatingErrorHandler , which, as I understand it, propagates the error further? Is there any other way to achieve the goal using only Java configuration (without XML)?

This is not a duplicate of this question , as it explicitly requests a solution based on the Java configuration, not XML (so this is to include Spring in the project without any XML configuration).

There are also some answers that demonstrate how to configure TaskScheduler from scratch. For example, this answer requires that you also determine the pool size, maximum pool size, and queue capacity. Here is a solution that also needs a very extensive configuration. The documentation shows how to configure other aspects, but not how to specify error handling. But , which is the minimum required effort with the Java configuration , so I can maximize Spring's default load values ​​(thread pools, artist configurations, etc.).

+9
source share
3 answers

As pointed out in the comments, @ExceptionHandler for Spring MVC controllers.

If you want to have exception handling logic for one scheduler, the easiest and most convenient for maintenance would be to turn it into a try-catch block and handle the error.

If you want to use the same error handler for different schedulers, follow @M. Dane's suggestion.

+4
source

Here is an example of setting up a custom error handler (Spring 2.0.2):

 @Bean public TaskScheduler taskScheduler() { ConcurrentTaskScheduler scheduler = new ConcurrentTaskScheduler(); scheduler.setErrorHandler(throwable -> { /* custom handler */ }); return scheduler; } 
+2
source

I think using AOP can solve your problem.

measures

  1. Create a class called UpdateJobAOP and add the annotations @Component and @Aspect.
  2. In the UpdateJobAOP class, create a method called all () and annotate with @Pointcut ("execution (* com.foo.bar.UpdateJob. * (..))")
  3. Create another method in the UpdateJobAOP class named afterThrowing (Exception ex) or any other and annotate with @AfterThrowing (pointcut = "all ()", throwing = "ex")
  4. Print a stack trace and see if any exceptions are found.

For your information : I worked on AOP on individual methods, caught exceptions and registered them, but I personally did not come up with the use case that you have indicated so far. The above solution is just a suggestion.

 @Aspect @Component public class UpdateJobAOP { @Pointcut("execution(* com.foo.bar.UpdateJob.*(..))") public void all() {} @AfterThrowing(pointcut="all()", throwing="ex") public void afterThrowing(Exception ex) { // Do what you want ex.printStackTrace(); } } 
0
source

Source: https://habr.com/ru/post/1012999/


All Articles