feign icon indicating copy to clipboard operation
feign copied to clipboard

Does not retry "java.io.IOException: Premature EOF" exceptions

Open elmozgo opened this issue 1 year ago • 1 comments

For WIremock's Fault.MALFORMED_RESPONSE_CHUNK Feign's retry mechanisms does not kick in and the exception is thrown without a retry. For Fault.CONNECTION_RESET_BY_PEER the retry mechanism works as expected.

I'm using the default Retryer (feign.Retryer.Default) and a custom ErrorDecoder (both are not invoked)

I've noticed the org.springframework.cloud.openfeign.support.SpringDecoder class mentioned in the stacktrace, if you think that this issue belongs to Spring Cloud Open Feign, I'm happy to move it there.

My test case is similar to this:

stubFor(get(urlPathEqualTo("/test-url"))
  .inScenario("retry test")
  .willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK))
  .willSetStateTo("failed once"));
stubFor(get(urlPathEqualTo("/test-url"))
  .inScenario("retry test")
  .whenScenarioStateIs("failed once")
  .willReturn(okJson(fromFile("response.json"))));

var response = feignClient.getTestUrl();
assertThat(response).isPresent();
verify(exactly(2), getRequestedFor(urlPathEqualTo("/test-url")));

I get an exception that is similar to this:

Feign.FeignException: Premature EOF reading GET http://localhost:11390/test-url

	at feign.FeignException.errorReading(FeignException.java:167)
	at feign.InvocationContext.proceed(InvocationContext.java:42)
	at feign.ResponseHandler.decode(ResponseHandler.java:122)
	at feign.ResponseHandler.handleResponse(ResponseHandler.java:73)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:114)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:70)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:96)
	...
	
Caused by: java.io.IOException: Premature EOF
	at java.base/sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:567)
	at java.base/sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:611)
	at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:705)
	at java.base/java.io.FilterInputStream.read(FilterInputStream.java:119)
	at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3674)
	at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3667)
	at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3655)
	at java.base/java.io.FilterInputStream.read(FilterInputStream.java:71)
	at java.base/java.io.PushbackInputStream.read(PushbackInputStream.java:147)
	at org.springframework.web.client.IntrospectingClientHttpResponse.hasEmptyMessageBody(IntrospectingClientHttpResponse.java:100)
	at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:90)
	at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:75)
	at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:61)
	at feign.optionals.OptionalDecoder.decode(OptionalDecoder.java:42)
	at feign.InvocationContext.proceed(InvocationContext.java:36)

Tested this on :

  • Spring Cloud Open Feign 4.0.2
  • Feign Core 12.4 (bumped from spring's 12.1)

elmozgo avatar Jul 18 '23 17:07 elmozgo