Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected FeignException instead of ResponseEntity when the server returns 401 #2312

Open
tsypanovs opened this issue Jan 26, 2024 · 1 comment

Comments

@tsypanovs
Copy link

Originally asked in https://stackoverflow.com/questions/77880702/unexpected-feignexception-instead-of-responseentity-when-the-server-returns-401

In our application we use spring-cloud-starter-openfeign:4.1.0 for some interservice communication. Here's one of our clients:

@FeignClient(name = "authClient", url = "${spring.microservice.tenant-auth.host}")
public interface AuthClient {
    @PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    ResponseEntity<AuthenticationResponse> getAuthToken(AuthFormData formData);
}

public class AuthFormData {

    private String grant_type;
    private String client_id;
    private String client_secret;

    public void setGrantType(String grantType) {
        this.grant_type = grantType;
    }

    public void setClientId(String clientId) {
        this.client_id = clientId;
    }

    public void setClientSecret(String clientSecret) {
        this.client_secret = clientSecret;
    }
}

public class AuthenticationResponse {

    @JsonProperty("access_token")
    private String accessToken;
    @JsonProperty("token_type")
    private String tokenType;
    @JsonProperty("expires_in")
    private int expiresIn;
    @JsonProperty("scope")
    private String scope;
    @JsonProperty("refresh_token")
    private String refreshToken;
    @JsonProperty("id_token")
    private String idToken;
}

In general this code works fine, but what puzzles me is the FeignException thrown from the callee in case the server returns 401:

AuthenticationResponse getToken(AuthFormData authFormData) {
    var authResponse = authClient.getAuthToken(authFormData);
    var body = authResponse.getBody();
    if (!authResponse.getStatusCode().is2xxSuccessful() || body == null) {
        throw new IllegalStateException("Failed to get auth token " + authResponse);
    }
    return body;
}

Here's the stacktrace:

feign.FeignException$Unauthorized: [401 Unauthorized] during [POST] to [https://somethin.com/oauth/token] [AuthClient#getAuthToken(AuthFormData)]: []
	at feign.FeignException.clientErrorStatus(FeignException.java:224) ~[feign-core-13.1.jar:na]
	at feign.FeignException.errorStatus(FeignException.java:203) ~[feign-core-13.1.jar:na]
	at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-13.1.jar:na]
	at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:103) ~[feign-core-13.1.jar:na]
	at feign.InvocationContext.decodeError(InvocationContext.java:126) ~[feign-core-13.1.jar:na]
	at feign.InvocationContext.proceed(InvocationContext.java:72) ~[feign-core-13.1.jar:na]
	at feign.ResponseHandler.handleResponse(ResponseHandler.java:63) ~[feign-core-13.1.jar:na]
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:114) ~[feign-core-13.1.jar:na]
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:70) ~[feign-core-13.1.jar:na]
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:99) ~[feign-core-13.1.jar:na]
	at jdk.proxy2/jdk.proxy2.$Proxy113.getAuthToken(Unknown Source) ~[na:na]
	at c.c.o.p.m.AuthenticationTokenProvider.getToken(AuthenticationTokenProvider.java:34) ~[classes/:0.0.1-SNAPSHOT]

If the response is 200 or 500 then the ResponseEntity with corresponding status code is returned.

So my question is why do I get exception for 401 and is there a way to make the AuthClient return ResponseEntity with 401?

@velo
Copy link
Member

velo commented Jan 26, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants