【发布时间】:2021-07-14 09:12:26
【问题描述】:
我有以下代码创建一个产品,然后在某种历史服务(journalClient)中记录创建成功。
如果日志客户端出现错误,我想回滚产品创建。
@Service
public class ProductService {
public Mono<ProductRS> createProduct(final ProductRQ rq) {
return productclient.createProduct(rq).flatMap(produktfamilieRS -> {
return journalClient.createJournalEntry("Dummy-Entry").thenReturn(productRS)
.doOnError(throwable -> {
log.error("Error creating journal Entry - Starting rollback of transaction.");
rollbackCreateProduct(productRS.getId());
});
});
private void rollbackCreateProduktfamilie(long id) {
productClient.deleteProduct(id).subscribe();
}
@Service
public class JournalClientMockImpl implements JournalClientMock {
public Mono<Void> createJournalEntry(String body, boolean error) {
throw new RuntimeExcpeption("Test Error");
}
我的问题是,我在 JournalClient 中抛出的 RuntimeException 不会触发 ProductService.createProduct 中的 Mono.doOnError()。
关键点:我发现返回 Mono.error 会触发外部 doOnError:
@Service
public class JournalClientMockImpl implements JournalClientMock {
public Mono<Void> createJournalEntry(String body, boolean error) {
return Mono.error(new RuntimeException("Beabsichtiger Fehler im JournalServiceMock"));
}
但我的问题是,我的业务逻辑中可能存在错误,导致 RuntimeExceptions 不会以 Mono.error 结尾。
我的坏主意:我唯一的想法就是做这样的事情......用一个包罗万象的东西包围整个代码:
public Mono<Void> createJournalEntry(String body, boolean error) {
try{
// do some business logic
// ...
// call journal web service
// ...
return Mono.empty();
} catch (Throwable e){
return Mono.error(new RuntimeException("Error in JournalServiceMock"));
}
}
这应该是解决方案吗?这闻起来像非常糟糕的设计。 如何正确执行此操作?
非常感谢
【问题讨论】:
-
Do on error 仅用于副作用,例如日志记录等。如果您希望切换到另一个发布者,您应该使用例如 onErrorResume。
标签: spring spring-webflux reactive