Reputation: 418
Suppose I have a supplier and some exception occurs while invoking get method of that supplier.
Supplier<> supplier = () -> getSomething();
ResilienceDecorator.executeSupplier( //Edit 1 - Could be ResilienceDecorator.executeCallable
supplier,
resilienceConfiguration,
throwable -> {
log.error("Exception occured", throwable);
return null;
});
Edit 1 - Also same for ResilienceDecorator.executeCallable
.
I need a consistent API to know what went wrong during execution i.e. What was the checked exception (Edit 1 - or Unchecked exception) causing the failure so I can
handle business logic. The throwable is not root cause of exception or whatever the supplier had thrown.
If we do not provide a throwable function like above then
every exception is wrapped in a ResilienceRuntimeException
and we need a chain of getCause().getCause()
to know what went wrong. This is internal to sdk which might change. Again a consistent API is needed.
Is there any alternative & consistent way to know what exception the supplier is throwing? I might need to bubble it up or write a user friendly message based on the exception occured, depending upon buisness logic.
Edit 1- An example of my current situation.
Supplier<MatDocItm> supplier = () -> {
ErpHttpDestination erpHttpDestination = DestinationAccessor.getDestination(S4_SYSTEM).asHttp().decorate(DefaultErpHttpDestination::new);
return new CustomCommand(erpHttpDestination, params).execute();
}
try {
MatDocItm = ResilienceDecorator.executeSupplier(
supplier,
configuration
);
} catch (ResilienceRuntimeException e) {
throw new ReadException("Failed to read from SAP S/4HANA", e);
}
The supplier can throw runtime exceptions and based on these exceptions I want to give a User friendly error message with proper description.
The supplier can throw a DestinationAccessException
(which is runtime exception) if a destination cannot be accessed, is not configured correctly, or does not fulfill certain prerequisites.
Not only the exceptions occured in supplier, I have TimeLimiterConfiguration
& if timeout occurs then a TimeoutException
can be thrown.
For above MatDocItm example the ResilienceRuntimeException.getCause()
will give com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException
. ResilienceRuntimeException.getCause().getCause()
will reveal exception that actually caused the error i.e DestinationAccessException
. Now ThreadContextExecutionException is internal to sdk and can change if sdk implementation changes. Will this implementation detail remain frozen and never change in future or is there any alternative way to get the root cause?
Upvotes: 1
Views: 224
Reputation: 938
I would recommend ExceptionUtils.throwableOfType
for matching exception type and sub classes.
Alternatively ExceptionUtils.throwableOfThrowable
for matching exact type only.
The utility class already provided by dependency org.apache.commons:commons-lang3:3.10
Example:
@Nullable
YourException cause = ExceptionUtils.throwableOfType(throwable, YourException.class);
You can handle the nullable result in an If statement.
As a fan of fluent APIs, I would rather go with java.util.Optional
or io.vavr.control.Option
.
Upvotes: 1