Robert Strauch
Robert Strauch

Reputation: 12896

Exception handling for Spring Boot @Async methods

I'm pretty new to Spring Boot. In a project I'd like to send an email asyncronously. Below, you can see what I have so far.

A problem I have is the following: An external system sends a POST request to the controller. If some exception occurs while building or sending the mail, then the GlobalExceptionHandler does not get called. As a consequence, the controller always returns an HTTP 201, so the caller assumes that everything went fine.

How would I integrate my exception handlers with @ControllerAdvice in such async methods?

Controller

@PostMapping(value = "/mail", consumes = MediaType.APPLICATION_JSON_VALUE)
public void send(@Validated @RequestBody EmailNotificationRequest emailNotificationRequest) throws MessagingException {
    emailService.sendMessage(emailNotificationRequest);
}

Service

@Async
public void sendMessage(EmailNotificationRequest emailNotificationRequest) throws MessagingException {
    MimeMessage mimeMessage = javaMailSender.createMimeMessage();

    // build the message

    javaMailSender.send(mimeMessage);
}

ExceptionHandler

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends AbstractExceptionHandler {

    /**
     * Handles any exception which is not handled by a specific {@link ExceptionHandler}.
     */
    @ExceptionHandler(value = {Throwable.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApplicationResponse handleThrowable(Throwable ex) {
        log.error("An unhandled error occurred: {}", ex.getMessage());
        return buildErrorResponse();
    }
}

Upvotes: 1

Views: 1831

Answers (2)

Vamsinag R
Vamsinag R

Reputation: 49

Instead of GlobalExceptionHandler, can you try with GlobalAsyncExceptionalHandler. Please refer the below

https://jhamukul007.medium.com/how-to-caught-async-exception-spring-boot-application-168126214deb

Upvotes: -1

riorio
riorio

Reputation: 6816

How about moving the @Async into a lower level, so only the

javaMailSender.send(mimeMessage);

Will be called in an async way?

Extract it to a different bean with a public async method that wraps the javaMailSender and remove the Async from the mothod of sendMessage

Upvotes: 1

Related Questions