![](/img/trans.png)
[英]Is there a .thenCompose() for CompletableFuture that also executes exceptionally?
[英]CompletableFuture thenCompose after exceptionally
我陷入了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);
}
});
}
}
看起來句柄方法應該有所幫助,但它返回CompletableFuture的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);
}
});
}
您可以預先轉換為保存狀態。
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));
}
另一個可行的解決方案:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.