在我的Sping Boot 应用程序中,我有一个方法,通过对SendGrid API进行(阻塞)HTTP调用来发送电子邮件。在某些情况下,我会在每个请求中多次调用此方法,因此为了减轻对请求线程的影响,我通过使用@Async
注解来异步调用此方法。
public class EmailService {
@Async
public void send(String address, String subject, String body) {
// make a HTTP call to SendGrid's API
}
}
public class PasswordService {
@Autowired
private EmailService emailService;
public void resetAll(String emailAddresses) {
emailAddresses.forEach(email -> {
emailService.send(email, "Your new password is", "open-sesame");
});
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handleException(Exception ex) {
ex.printStackTrace();
}
}
字符串
这种方法的问题是它绕过了应用程序的异常处理。如果emailService.send
抛出异常,则不会调用全局异常处理程序,因此不会向客户端返回500 HTTP状态。
如果我删除@Async
,全局异常处理程序将按预期调用。如何异步调用此方法,而不绕过全局异常处理程序?
2条答案
按热度按时间dohp0rv51#
如果我理解正确的话,您希望处理异步任务,但在出现错误时,使错误处理同步并通知用户。
如果不改变你的逻辑,这似乎是不可能的定义.你做的cnrc调用,因为你不想让用户等待繁重的处理,即响应速度比繁重的进程,但你想等待,如果它的错误,你不能预见.我认为你必须改变你的方式来处理这种情况下,需要重新考虑你的逻辑.
更复杂的方法是通过WebSocket连接或从客户端到服务器的常量轮询来处理错误处理,其中错误处理程序通知用户。这意味着用户会延迟错误。
一个更简单的方法是允许用户再次运行该过程“没有邮件?再次发送邮件”或类似的东西。
ni65a41a2#
根据评论,似乎我没有很好地解释这个问题。我已经测试了下面的解决方案,并对它满足我的要求感到满意
字符串