CompletableFuture thenCompose после исключительно - PullRequest
0 голосов
/ 26 октября 2018

Я застрял с обработкой исключений CompletableFuture

Моя логика - отправлять электронную почту и сохранять статус этого действия.Если отправка электронной почты вызывает исключение, мне нужно сохранить статус с сообщением об исключении.

public interface MyService {
CompletableFuture<Boolean> sendEmail(String content, String address);
CompletableFuture<StatusResult> saveStatus(String content, String address);}

Класс процессора в настоящее время имеет этот код.Работает нормально, но не изящно как у меня.Как мы можем избавиться от локального поля ошибок, которое мы используем для совместного использования состояния между этапами?

@Component
public class Processor {
    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class);
    @Autowired
    private MyService myService;

    public CompletableFuture<StatusResult> sendEmail(String content, String address) {
        AtomicReference<String> error = new AtomicReference<>();// just to forward error message from exception block to thenCompose
        return myService.sendEmail(content, address).exceptionally(e -> {
            LOGGER.error("Exception during send email ", e);
            error.set(e.getMessage());
            return null;
        }).thenCompose(x -> {
            if (x == null) {
                return myService.saveStatus(error.get(), address);
            } else {
                return myService.saveStatus("good", address);
            }
        });

    }
}

Похоже, метод handle должен помочь, но он возвращает CompletableFuture of CompletableFuture

 public CompletableFuture<StatusResult> sendEmail(String content, String address) {
    CompletableFuture<CompletableFuture<StatusResult>> result = myService.sendEmail(content, address).handle((x, e) -> {
        if (e != null) {
            LOGGER.error("Exception during send email ", e);
            return myService.saveStatus("error", address);
        } else {
            return myService.saveStatus("good", address);
        }
    });
}

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Вы можете конвертировать в свой статус сохранения заранее.

public CompletableFuture<String> sendEmail(String content, String address) {

    return myService.sendEmail(content, address)
            .thenApply(b -> "good")
            .exceptionally(Throwable::getMessage)
            .thenCompose(status -> myService.saveStatus(status, address));
}
0 голосов
/ 26 октября 2018

Другое рабочее решение:

public CompletableFuture<StatusResult> sendEmailAndSaveStatus(String content, String address) {
    CompletableFuture<Boolean> sendEmail = myService.sendEmail(content, address);
    CompletableFuture<StatusResult> result = new CompletableFuture<>();
    sendEmail.exceptionally(e -> {
        LOGGER.info("Exception during send email ");
        myService.saveStatus(e.getMessage(), address).thenApply(x -> result.complete(x));
        return false;
    });
    sendEmail.thenCompose(x -> myService.saveStatus("good", address)).thenApply(x -> result.complete(x));
    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...