feign icon indicating copy to clipboard operation
feign copied to clipboard

Retry issue after migration to 13.5

Open sergey-morenets opened this issue 1 year ago • 6 comments

Hi

We use feign-java11 and feign-gson dependencies in our project and after we migrated from 13.1 to 13.5 one of our tests started failing. This test uses WireMock and verifies that if malformed response is sent to the client then RetryableException is thrown.

extension.stubFor(post(urlEqualTo("/cities")).willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
assertThrows(RetryableException.class, () -> cityClient.create(city));

In 13.1 this test passed but in 13.5 fails. Our investigation shown that in both Feign versions IOException is thrown but in 13.1 it's correctly caught in SynchronousMethodHandler.executeAndDecode:

java.io.IOException: chunked transfer encoding, state: READING_LENGTH

And in 13.5 it's not caught. The last line that was executed is

cf = sendAsync(req, responseHandler, null, null);

in HttpClientImpl.send

sergey-morenets avatar Dec 09 '24 22:12 sergey-morenets

Our deeper analysis shown that this regression appeared in 13.3 and possible reason is the replacement

httpResponse = clientForRequest.send(httpRequest, BodyHandlers.ofByteArray());

with

httpResponse = clientForRequest.send(httpRequest, BodyHandlers.ofInputStream());

in Http2Client.

sergey-morenets avatar Dec 09 '24 23:12 sergey-morenets

So IOException actually happens then we try to read response body (in IOUtils.toString):

var response = cityClient.create(city);
var body = IOUtils.toString(response.body().asInputStream(), Charset.defaultCharset());

And main issue is that this exception occurs outside of Feign client and that means retry logic would not be executed.

sergey-morenets avatar Dec 10 '24 09:12 sergey-morenets

If cityClient.create(city) returns a feign.Response, it should indeed handle the inputStream related exceptions by itself.

If you want to reproduce the previous logic, the return type should be filled with byte[]. eg: cityClient

byte[] create(var city)

hdfg159 avatar Dec 27 '24 06:12 hdfg159

Hi @hdfg159

I'm fine with that but it's breaking change and should be mentioned in release notes and documentation.

sergey-morenets avatar Dec 28 '24 08:12 sergey-morenets

Hi @hdfg159

I'm fine with that but it's breaking change and should be mentioned in release notes and documentation.

This should be a bug -> #2419 . If it's version 13.1, then using other clients(eg: apache httpclient or okhttp3) should yield different expected results.

hdfg159 avatar Dec 28 '24 14:12 hdfg159

If cityClient.create(city) returns a feign.Response, it should indeed handle the inputStream related exceptions by itself.

If you want to reproduce the previous logic, the return type should be filled with byte[]. eg: cityClient

byte[] create(var city)

https://github.com/OpenFeign/feign/issues/1474#issuecomment-1079034311

hdfg159 avatar Dec 28 '24 14:12 hdfg159