I want to throw Exceptions that are extended from Exception
if Try.ofCallable()
fails.
I have a callable of the type:
final Callable<MyResponse> decoratedCallable =
circuitBreakerService.getDecoratedMethod(
myArg1,
() -> myFunction(myArg1, myArg2, myArg3)
);
I am trying something like this:
Try.ofCallable(decoratedCallable).onFailure(throwable -> {
if (throwable instanceof CallNotPermittedException) {
throw new MyRuntimeExceptionA("msg1", throwable);
} else {
throw new MyRuntimeExceptionB("msg2", throwable);
}
});
This works (the function that wraps the above two statements throws the correct exception MyRuntimeExceptionA and MyRuntimeExceptionB) if both MyRuntimeExceptionA
and MyRuntimeExceptionB
extend RuntimeException
, but not if they extend Exception
.
If they extend Exception
then I am not able to throw them from the main function.
The IDE asks to wrap them in try/catch - which I don't want.
You have two options. You can throw when you try to unwrap the Try
by getting the value with the following code:
Try.ofCallable(decoratedCallable)
.getOrElseThrow(throwable -> {
if (throwable instanceof CallNotPermittedException) {
return new MyExceptionA("msg1", throwable);
} else {
return new MyExceptionB("msg2", throwable);
}
})
or move out the error mapping code to before unwrapping with a similar code:
Try.ofCallable(decoratedCallable)
.mapFailure(
Case(
$(instanceOf(CallNotPermittedException.class)),
throwable -> new MyExceptionA("msg1", throwable)
),
Case($(), throwable -> new MyExceptionB("msg2", throwable))
)
.get()
Both solutions will only throw when unrwapping, so if you want to throw early, you will have to unwrap early.
Otherwise, I would take the advice others posted in comments not to throw exceptions if you are using Try
. The whole point in using Try
is to work with total functions instead of partial functions that can throw exceptions.