Closed mkopylec closed 3 years ago
A quick solution for Spring MVC would be to create a custom decorator here:
Custom decorator:
static Supplier<HttpResponse> decorateSupplier(CircuitBreaker circuitBreaker, Supplier<HttpResponse> supplier){
return () -> {
circuitBreaker.acquirePermission();
long start = System.nanoTime();
try {
HttpResponse response = supplier.get();
long durationInNanos = System.nanoTime() - start;
HttpStatus statusCode = response.getStatusCode();
if(!statusCode.is5xxServerError()){
circuitBreaker.onSuccess(durationInNanos);
return returnValue;
}else{
circuitBreaker.onError(new HttpServerErrorException(statusCode));
return returnValue;
}
} catch (Exception exception) {
// Do not handle java.lang.Error
long durationInNanos = System.nanoTime() - start;
circuitBreaker.onError(durationInNanos, exception);
throw exception;
}
};
A quick solution for Spring WebFlux would be to wrap a 5xx response into an Mono.error
and then unwrap the response again.
return execution.execute(request)
.onStatus(HttpStatus::is5xxServerError, response ->
Mono.error(new HttpServerException(response))
)
.transform(of(circuitBreaker))
.onErrorResume(CallNotPermittedException.class, ex -> just(executeFallback(ex)))
.onErrorResume(HttpServerException.class, ex -> just(ex.getResponse())
I know I can do it on my own but I would rather not to have "hacks" like those in the code. I will continue to work on https://github.com/resilience4j/resilience4j/issues/384
Done in 4.8.0
To implement the feature https://github.com/resilience4j/resilience4j/issues/384 needs to be implemented first.