处理 Spring @Async 方法抛出的异常

问题描述 投票:0回答:1

在我的 Spring 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
,全局异常处理程序将按预期调用。 如何异步调用此方法,而不绕过全局异常处理程序?

java spring spring-boot asynchronous
1个回答
1
投票

如果我理解正确,您想要处理异步任务,但如果出现错误,请同步处理错误并通知用户。

在不改变你的逻辑的情况下,根据定义这似乎是不可能的。您进行异步调用是因为您不希望用户等待繁重的处理,即响应比繁重的处理更快,但如果出现您无法预见的错误,您希望等待。我认为你必须改变处理这种情况的方式,这需要重新思考你的逻辑。

更复杂的方法是通过 WebSocket 连接或从客户端到服务器的持续轮询来处理错误,其中错误处理程序通知用户。这意味着用户会延迟收到错误。

更简单的方法是允许用户再次运行该过程“没有邮件?再次发送邮件”或类似的内容。

© www.soinside.com 2019 - 2024. All rights reserved.