I am facing an issue since I enabled turned a synchronous method into an asynchronous one: if an exception is thrown from within the body of the method, I can no longer rethrow it.
Let me first show the code:
My async/task executor configuration:
@Configuration @EnableAsync public class AsyncConfiguration implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(5); taskExecutor.setMaxPoolSize(10); taskExecutor.setQueueCapacity(25); taskExecutor.initialize(); return taskExecutor; } }
My asynchronous method:
@Async @Override public void sendPasswordResetInfo(String email) { Assert.hasText(email); Member member = memberRepository.findByEmail(email); try { mailerService.doMailPasswordResetInfo(member);//EXCEPTION THROWN HERE } catch (MessagingException | MailSendException e) { log.error("MessagingException | MailSendException", e); // TODO: not thrown since @Async is used throw new MailerException("MessagingException | MailSendException");//NOT CALLED } }
All I see in the console when an exception is raised by mailerService.doMailPasswordResetInfo
is the following stacktrace:
2014-06-20 18:46:29,249 [ThreadPoolTaskExecutor-1] ERROR com.bignibou.service.preference.PreferenceServiceImpl - MessagingException | MailSendException org.springframework.mail.MailSendException: Failed messages: javax.mail.SendFailedException: Invalid Addresses; nested exception is: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418] ; message exception details (1) are: Failed message 1: javax.mail.SendFailedException: Invalid Addresses; nested exception is: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418] at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1294) at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:635) at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:424) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:346) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:341) at com.bignibou.service.mailer.MailerServiceImpl.doMailPasswordResetInfo(MailerServiceImpl.java:82) at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo_aroundBody10(PreferenceServiceImpl.java:112) at com.bignibou.service.preference.PreferenceServiceImpl$AjcClosure11.run(PreferenceServiceImpl.java:1) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59) at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63) at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo_aroundBody12(PreferenceServiceImpl.java:108) at com.bignibou.service.preference.PreferenceServiceImpl$AjcClosure13.run(PreferenceServiceImpl.java:1) at org.springframework.scheduling.aspectj.AbstractAsyncExecutionAspect.ajc$around$org_springframework_scheduling_aspectj_AbstractAsyncExecutionAspect$1$6c004c3eproceed(AbstractAsyncExecutionAspect.aj:58) at org.springframework.scheduling.aspectj.AbstractAsyncExecutionAspect.ajc$around$org_springframework_scheduling_aspectj_AbstractAsyncExecutionAspect$1$6c004c3e(AbstractAsyncExecutionAspect.aj:62) at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo(PreferenceServiceImpl.java:108) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:97) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418] at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1145) ... 28 more
FYI, MailerException
is a custom exception I used in the app. What really strikes me is that this MailerException
exception does not appear to be caught nor rethrown...
Can anyone please help?
edit 1: I have modified my async service method as follows:
@Async @Override public Future<Void> sendPasswordResetInfo(String email) { Assert.hasText(email); Member member = memberRepository.findByEmail(email); try { mailerService.doMailPasswordResetInfo(member); return new AsyncResult<Void>(null); } catch (MessagingException | MailSendException e) { log.error("MessagingException | MailSendException", e); //HERE: HOW DO I SEND THE MailerException USING THE FUTURE?? throw new MailerException("MessagingException | MailSendException"); } }
However, I am not sure how to send the MailerException to the web layer using the AsyncResult from within the catch block above...