feign icon indicating copy to clipboard operation
feign copied to clipboard

How to handle response and HTTP-status directly in decoder?

Open a96219 opened this issue 3 years ago • 9 comments

in class feign.AsyncResponseHandler

      if (Response.class == returnType) {
        if (response.body() == null) {
          resultFuture.complete(response);
        } else if (response.body().length() == null
            || response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {
          shouldClose = false;
          resultFuture.complete(response);
        } else {
          // Ensure the response body is disconnected
          final byte[] bodyData = Util.toByteArray(response.body().asInputStream());
          resultFuture.complete(response.toBuilder().body(bodyData).build());
        }
      } else if (response.status() >= 200 && response.status() < 300) {
        if (isVoidType(returnType)) {
          resultFuture.complete(null);
        } else {
          final Object result = decode(response, returnType);
          shouldClose = closeAfterDecode;
          resultFuture.complete(result);
        }
      } else if (decode404 && response.status() == 404 && !isVoidType(returnType)) {
        final Object result = decode(response, returnType);
        shouldClose = closeAfterDecode;
        resultFuture.complete(result);
      } else {
        resultFuture.completeExceptionally(errorDecoder.decode(configKey, response));
      }

decoder only takes effect when http-status=404 or http-status>=200 && http-status < 300 Whether the decoder can be configured to take effect directly so that the user handles http-status and response himself ? just like Feign.Builder.forceDecoding=true,but Feign.Builder.forceDecoding not public

a96219 avatar Feb 23 '22 03:02 a96219

In my opinion you could implement both Decoder and ErrorDecoder (in one class or two separate ones): first as you say for the range 200-300 and second for other. Both ErrorDecoder.decode and Decoder.decode have argument Response.

vitalijr2 avatar Feb 26 '22 08:02 vitalijr2

In my opinion you could implement both Decoder and ErrorDecoder (in one class or two separate ones): first as you say for the range 200-300 and second for other. Both ErrorDecoder.decode and Decoder.decode have argument Response.

But ErrorDecoder.decode must throw an exception. It would be nice to have a configuration like Feign.Builder.forceDecoding, or other forms of intervention.

a96219 avatar Feb 28 '22 01:02 a96219

This is our intent, that all responses > 399 are passed off to error decoder as, defined by the HTTP spec, they are considered errors. The Decoder and ErrorDecoder are the components responsible for parsing and managing the responses. If you are looking to manage the request and response objects directly, then you are by passing most of what Feign offers.

I recommend you read through our examples again and see if you need what we offer or may be better off with using an HTTP client directly.

kdavisk6 avatar Mar 24 '22 13:03 kdavisk6

This is our intent, that all responses > 399 are passed off to error decoder as, defined by the HTTP spec, they are considered errors. The Decoder and ErrorDecoder are the components responsible for parsing and managing the responses. If you are looking to manage the request and response objects directly, then you are by passing most of what Feign offers.

I recommend you read through our examples again and see if you need what we offer or may be better off with using an HTTP client directly.

I define 'fallback' to solve this problem. When response Status is greater than 399, sometimes the response body can continue to run without throwing an exception, like status=404.

a96219 avatar Mar 30 '22 03:03 a96219

I extend feign.Logger and override logAndRebufferResponse , use response.toBuilder() rebuild the response in logAndRebufferResponse。

wpinchine avatar Apr 27 '22 13:04 wpinchine

Simply put, Feign treats status codes above 399 as errors. 404 is a Client error, NOT_FOUND. We do have escape hatches specifically for 404 you can use, but they will ultimately end up in an ErrorDecoder

kdavisk6 avatar Oct 07 '22 21:10 kdavisk6

This is our intent, that all responses > 399 are passed off to error decoder as, defined by the HTTP spec, they are considered errors. The Decoder and ErrorDecoder are the components responsible for parsing and managing the responses. If you are looking to manage the request and response objects directly, then you are by passing most of what Feign offers. I recommend you read through our examples again and see if you need what we offer or may be better off with using an HTTP client directly.

I define 'fallback' to solve this problem. When response Status is greater than 399, sometimes the response body can continue to run without throwing an exception, like status=404.

Can you provide an example code? I just encountered a similar problem. Thank you.

cat-cx avatar Mar 15 '23 08:03 cat-cx

This is our intent, that all responses > 399 are passed off to error decoder as, defined by the HTTP spec, they are considered errors. The Decoder and ErrorDecoder are the components responsible for parsing and managing the responses. If you are looking to manage the request and response objects directly, then you are by passing most of what Feign offers. I recommend you read through our examples again and see if you need what we offer or may be better off with using an HTTP client directly.

I define 'fallback' to solve this problem. When response Status is greater than 399, sometimes the response body can continue to run without throwing an exception, like status=404.

Can you provide an example code? I just encountered a similar problem. Thank you.

I am using spring-cloud-starter-openfeign, see this link feign-fallback

a96219 avatar Mar 20 '23 08:03 a96219

Greetings. I think it's wrong to assume that a "bad" HTTP status always constitutes an exception from the caller's point of view. As a QA engineer, a lot of times I actually expect those, and rather getting a 200 is the exception. For my use case it would be convenient If I could configure Feign to pass raw response to my custom Decoder independently of the status code received. Then I could have some sort of Response<T> class as the return type covering both positive and negative responses.

psmyt avatar Feb 02 '24 09:02 psmyt