I am using resilience4j's TimeLimiter to control timeout requests for a RestTemplate call. I am throwing a custom exception if the response.getBody() is null but, resilience4j's always throwing exception provided in getorElseThrow. how can I throw a custom exception here?
Try.ofCallable(methodWhichThrowsCustomException).getOrElseThrow(throwable -> {throw new ApplicationException(HttpStatus.REQUEST_TIMEOUT,
ErrorConstant.ERROR_CODE_REQUEST_TIMEOUT, ErrorConstant.ERROR_MESSAGE_TIME_OUT);
});
}
Here i am trying throw the exception that the "methodWhichThrowsCustomException" throws, but i am not able to do that it only throws the exception the thrown here.
I don't know resilience4j
but I'm pretty sure you are using getOrElseThrow
wrong. The syntax you most likely want is this:
Try.ofCallable(methodWhichThrowsCustomException())
.getOrElseThrow(throwable -> new ApplicationException(HttpStatus.REQUEST_TIMEOUT, ErrorConstant.ERROR_CODE_REQUEST_TIMEOUT, ErrorConstant.ERROR_MESSAGE_TIME_OUT));
Note that you don't need to throw
inside getOrElseThrow
, you only need to return the new exception to throw, Vavr will take care of throwing it.
Try.of().getOrElseThrow()
See the blog Vavr One Log 03 - A Safe Try :
T getOrElseThrow(Supplier)
getOrElseThrow
expects an exception-supplier as argument. This may be a lambda, method-reference, or any functional. Its purpose is to map the thrown exception to your instance of a custom Exception. For example:
Try.ofCallable(methodWhichThrowsCustomException)
.getOrElseThrow(throwable -> new CustomerException(
HttpStatus.REQUEST_TIMEOUT,
ErrorConstant.ERROR_CODE_REQUEST_TIMEOUT,
ErrorConstant.ERROR_MESSAGE_TIME_OUT,
throwable
))
}
Note: we use throwable -> new ..
inside parentheses, nothing more. The exception instance is just created (and returned implicitly), we do not throw it - we supply it to vavr which throws then.
You passed a consumer instead. The consuming lambda { throw new ...; }
{ throw new ...; }
is throwing a new Exception immediately instead of simply mapping it with { return new CustomException("Custom message", thrown); }
{ return new CustomException("Custom message", thrown); }
.
Try.of
applied to CircuitBreaker: Decorate and execute a functional interfaceTimeLimiter
throw the exception that the "methodWhichThrowsCustomException" throws
Assume you have a method:
public String sayHelloWorld(boolean shouldThrow) throws CustomException {
if (shouldThrow) throw new CustomException("Hello Exception");
return "Hello World!";
}
You pass this to the TimeLimiter
When it executes and it was not able to complete successfully within time, it throws either of two exceptions
TimeoutException
:When a timeout occurs, it cancels the running Future before throwing a
TimeoutException
.
ExecutionException
, like when your method throws a custom exception, it will find that cause and rethrow this exception. See TimeLimiterImpl
, catch-block, line 57 .Then you should be able to catch it:
try {
// The blocking variant which is basically future.get(timeoutDuration, MILLISECONDS)
String result = timeLimiter.executeFutureSupplier(
() -> CompletableFuture.supplyAsync(() -> sayHelloWorld(true)));
log.info(result);
} catch (Exception e) {
log.error(e); // or print to debug, handle, etc.
}
or using Vavr's Try :
String result = Try.of(() -> timeLimiter.executeFutureSupplier(
() -> CompletableFuture.supplyAsync(() -> sayHelloWorld(true))) // method forced to throw
).getOrElseThrow(throwable -> throwable); // will throw as is (without mapping to another exception)
log.info(result);
See also:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.