I have the following Code that creates a product and then logs the creation-success in some kind of history service (the journalClient).
If there is an error in the journal client I want to rollback the product creation.
@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");
}
My problem is, that the RuntimeException that I throw in the JournalClient does not trigger the Mono.doOnError() in the ProductService.createProduct.
Sticking Point: I found out that returning an Mono.error triggers the outer doOnError:
@Service
public class JournalClientMockImpl implements JournalClientMock {
public Mono<Void> createJournalEntry(String body, boolean error) {
return Mono.error(new RuntimeException("Beabsichtiger Fehler im JournalServiceMock"));
}
But my problem with that is, that there could be errors in my business logic that cause RuntimeExceptions that will not end in a Mono.error.
My bad idea: The only idea I have is to do something like this....surrounding the whole code with a catch-all:
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"));
}
}
Should this be the solution? This smells like very bad design. How to do this properly?
Thank you very much