Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Async Uncaught Exception handler

@Override @Async public void asyncExceptionTest() {     int i=1/0; } 

How can I log this using Spring Async framework without having to put try catch around every async method? It doesn't seem to pass to the DefaultUncaughtExceptionHandler like normal.

like image 550
DD. Avatar asked Jan 05 '12 00:01

DD.


People also ask

How does @async work in Spring?

Simply put, annotating a method of a bean with @Async will make it execute in a separate thread. In other words, the caller will not wait for the completion of the called method. One interesting aspect in Spring is that the event support in the framework also has support for async processing if necessary.

What is SimpleAsyncUncaughtExceptionHandler?

public class SimpleAsyncUncaughtExceptionHandler extends Object implements AsyncUncaughtExceptionHandler. A default AsyncUncaughtExceptionHandler that simply logs the exception.


1 Answers

@Async methods can be configured with a custom Executor to log any thrown exceptions.

The following code implements this pattern. Any method tagged with @Async will use the Executor returned by the method public Executor getAsyncExecutor(). This returns the HandlingExecutor which takes care of all logging (in this case it just prints the word "CAUGHT!" but you can replace with logging.

@Configuration @EnableAsync public class ExampleConfig implements AsyncConfigurer {     @Bean     public Runnable testExec() {         return new TestExec();     }      @Override     public Executor getAsyncExecutor() {         final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();         executor.setCorePoolSize(7);         executor.setMaxPoolSize(42);         executor.setQueueCapacity(11);         executor.setThreadNamePrefix("MyExecutor-");         executor.initialize();         return new HandlingExecutor(executor);     } }  public class HandlingExecutor implements AsyncTaskExecutor {     private AsyncTaskExecutor executor;      public HandlingExecutor(AsyncTaskExecutor executor) {         this.executor = executor;     }      @Override     public void execute(Runnable task) {         executor.execute(task);     }      @Override     public void execute(Runnable task, long startTimeout) {         executor.execute(createWrappedRunnable(task), startTimeout);     }      @Override     public Future<?> submit(Runnable task) {         return executor.submit(createWrappedRunnable(task));     }      @Override     public <T> Future<T> submit(final Callable<T> task) {         return executor.submit(createCallable(task));     }      private <T> Callable<T> createCallable(final Callable<T> task) {         return new Callable<T>() {             @Override             public T call() throws Exception {                 try {                     return task.call();                 } catch (Exception e) {                     handle(e);                     throw e;                 }             }         };     }      private Runnable createWrappedRunnable(final Runnable task) {         return new Runnable() {             @Override             public void run() {                 try {                     task.run();                 } catch (Exception e) {                     handle(e);                 }             }         };     }      private void handle(Exception e) {         System.out.println("CAUGHT!");     } } 
like image 156
DD. Avatar answered Sep 30 '22 22:09

DD.