Describe the bug
I cannot find any information whether it is intended,
Exception is wrapped by NoFallbackAvailableException even using @CircuitBreaker fallbackMethod
Sample
This is my @FeignClient with @CircuitBreaker
@FeignClient(name = "ExchangeRateOpenFeign", url = "${exchange.currency.api.uri}")
public interface ExchangeRateOpenFeign {
Logger log = LoggerFactory.getLogger(ExchangeRateOpenFeign.class);
@CircuitBreaker(name = "currency", fallbackMethod = "fallback")
@GetMapping
ExchangeRateResponse call(
@RequestHeader String apiKey,
@RequestParam Currency source,
@RequestParam Currency currencies);
default ExchangeRateResponse fallback(
@RequestHeader String apiKey,
@RequestParam Currency source,
@RequestParam Currency currencies,
Throwable e) throws Throwable {
log.error("Here it comes with error", e);
throw e;
}
}
Then test below is passed
@SpringBootTest
class ExchangeRateOpenFeignTest {
@Autowired
private ExchangeRateOpenFeign openFeign;
@Test
void errorWrappedWithNoFallbackAvailableException() {
assertThatThrownBy(() -> openFeign.call("key", Currency.JPY, Currency.KRW))
.isInstanceOf(NoFallbackAvailableException.class);
}
}
Also I can get an error logs with NoFallbackAvailableException (Some logs have been omitted.)
2023-02-08 11:24:33.456 ERROR 65842 --- [pool-1-thread-1] c.m.o.a.openfeign.ExchangeRateOpenFeign : Here it comes with error
org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException: No fallback available.
at org.springframework.cloud.client.circuitbreaker.CircuitBreaker.lambda$run$0(CircuitBreaker.java:31) ~[spring-cloud-commons-3.1.5.jar:3.1.5]
at io.vavr.control.Try.lambda$recover$6ea7267f$1(Try.java:949) ~[vavr-0.10.2.jar:na]
at io.vavr.control.Try.of(Try.java:75) ~[vavr-0.10.2.jar:na]
at io.vavr.control.Try.recover(Try.java:949) ~[vavr-0.10.2.jar:na]
at org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreaker.run(Resilience4JCircuitBreaker.java:133) ~[spring-cloud-circuitbreaker-resilience4j-2.1.5.jar:2.1.5]
at org.springframework.cloud.client.circuitbreaker.CircuitBreaker.run(CircuitBreaker.java:30) ~[spring-cloud-commons-3.1.5.jar:3.1.5]
...
Caused by: feign.FeignException$BadRequest: [400] during [GET] to [http://localhost:8090/currency_data/live?source=JPY¤cies=KRW] [ExchangeRateOpenFeign#call(String,Currency,Currency)]: []
at feign.FeignException.clientErrorStatus(FeignException.java:213) ~[feign-core-11.10.jar:na]
at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-11.10.jar:na]
at feign.FeignException.errorStatus(FeignException.java:185) ~[feign-core-11.10.jar:na]
...
Since the fallbackmethod is specified, I don't think the error should be wrapped. But it is wrapped where it is called from FeignCircuitBreakerInvocationHandler.java
What I found is that, it is happend by calling fallbackMethod from resilence4J FallbackDecorators.
As Object with @CircuitBreaker is proxy and when resilence4J calls fallbackMethod By DefaultFallbackDecorator,
FeignCircuitBreakerInvocationHandler.java is called and error is wrapped when fallback method is called
Thanks for reading!
Comment From: cbezmen
Hey @MangKyu Could you give more information about the spring version and cloud version you are using?
I created a sample repository to understand more about your problem. As far as I can see it doesn't throw NoFallbackAvailableException. One more question from my side why do you want to throw an exception on fallback?
Feel free to add a commit or create a branch so I can check on that. https://github.com/cbezmen/can-feign/tree/b-MangKyu
Comment From: MangKyu
@cbezmen hi can, Thanks for your kindness! I uploaded on my repository which is forked Because 403 forbidden occurs
It occurs when enable circuitbreaker by spring.cloud.openfeign.circuitbreaker.enabled value as true.
Because there is no FeignClient`s fallback or fallbackFactory, FeignCircuitBreakerInvocationHandler.java runs with spring-cloud-commons CircuitBreaker interface which wraps exception by NoFallbackAvailableException
In my case, i have something like license code and if it fails to find, exception needs to be thrown.
Comment From: cbezmen
Hey @MangKyu
I updated my branch. you can see diff via there or in here.
If you are using spring open feign, you shouldn't use @CircuitBreaker. There is already an implementation for fallbacks. There is documentation in here. Spring open-feign checks for fallback implementation in the@FeignClient annotation. If it is not implemented it will wrap it with NoFallbackAvailableException.
Comment From: MangKyu
Thanks for reply!
I should avoid using @CircuitBreaker with Open Feign.
Thanks!