question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Spring Boot - fallback not registering

See original GitHub issue

I’m running into a problem with circuit breakers and fallbacks in my Spring Boot project. I have the following method.

@CircuitBreaker(name = "authorize", fallbackMethod = "fallback")
public TokenData authorize(MultiValueMap<String, String> body) {

    String uri = UriComponentsBuilder.fromUriString(vendorData.getAuthenticationUri())
            .build()
            .encode()
            .toString();

    OAuth2AuthorizationResponse response = restTemplate
            .postForEntity(uri, authorizationRequest, OAuth2AuthorizationResponse.class)
            .getBody();

    return buildToken(response);
}

private TokenData fallback(MultiValueMap<String, String> body) {
    return null;
}

This is working as expected. If postForEntity() throws an exception, the fallback is invoked and the method returns null. If the fallback’s signature is changed to something invalid, a NoSuchMethodFoundException will be thrown by resilience4j.

However, if I separate the network call from the authorize method like so:

public TokenData authorize(MultiValueMap<String, String> body) {

    String uri = UriComponentsBuilder.fromUriString(vendorData.getAuthenticationUri())
            .build()
            .encode()
            .toString();

    OAuth2AuthorizationResponse response = doAuthorizationRequest(uri, new HttpEntity<>(body, getHeaders()));

    return buildToken(response);
}

@CircuitBreaker(name = "authorize", fallbackMethod = "fallback")
public OAuth2AuthorizationResponse doAuthorizationRequest(String uri,
                                                           HttpEntity<MultiValueMap<String, String>> authorizationRequest) {
    return restTemplate
            .postForEntity(uri, authorizationRequest, OAuth2AuthorizationResponse.class)
            .getBody();
}

private OAuth2AuthorizationResponse fallback(String uri,
                                             HttpEntity<MultiValueMap<String, String>> authorizationRequest,
                                             Throwable t) {
    return null;
}

The fallback is neither triggered, nor even registered in the first place. The exception thrown by postForEntity will not trigger the fallback in this case, and will be thrown as if the annotation wasn’t even there in the first place. Even if I intentionally give the fallback an invalid signature, I won’t get an exception. Am I doing something wrong? Are circuit breakers not supported for nested methods?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
benteincommented, Jul 5, 2019

@RobWin Thanks, that was both informative and helpful. Now I know how to achieve what I set out to do.

1reaction
Romehcommented, Jul 4, 2019

@bentein for fallback you do not need to have it public , we check if it is private we make it accessible for invocation then we set back to original access level after that through reflection ,

for fallback to be invoked , you need to add just ONE extra target exception parameter to the fallback method to make it work , it is not optional , so the fallback method should has the same original method signature plus the original method params and one extra exception param at the end :

So should works in ur case

private OAuth2AuthorizationResponse fallback(String uri,
                                             HttpEntity<MultiValueMap<String, String>> authorizationRequest, Exception test) {
    return null;
}

if you want to have global fallback in case u have many methods that has the same return type , you can define one global fallback with JUST one parameter which the exception type

https://resilience4j.readme.io/docs/getting-started-3 here you can see the explanation of fallback logic

Last question are sure ur first version works ? can u debug and make sure it is triggered from ur fallback method ?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Call is not going to fallback method of Resilience4 Circuit ...
I am using Resilience4j Circuit breaker version: '1.4.0 with Spring boot version 2.0.6 and my problem is - fallback method is not working....
Read more >
Spring Cloud OpenFeign
In case the server is not running or available a packet results in connection refused. The communication ends either with an error message...
Read more >
Spring Native documentation
During the native compilation, you will see a lot of WARNING: Could not register reflection metadata messages. They are expected and will be ......
Read more >
Spring Boot Reference Documentation
Try the How-to documents. They provide solutions to the most common questions. Learn the Spring basics. Spring Boot builds on many other Spring...
Read more >
3. Circuit Breaker: Hystrix Clients - Spring Cloud
In cases of error and an open circuit, a fallback can be provided by the ... Hystrix does not let multiple Hystrix concurrency...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found