bjwzds
bjwzds

Reputation: 133

Openfeign ErrorDecoder caused java.io.IOException: stream is closed

When i try to implements ErrorDecoder to decode the feign exception, i found the stream in response.body() is closed, so when i try to read the stream and trans to string, it throw java.io.IOException: stream is closed. It's really confused because before the decoder, i didn't do anything to closed the stream advanced.

public class FeignClientErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        log.info("feign client response: {}", response);
        String body = null;
        try {
            body = Util.toString(response.body().asReader(Charset.defaultCharset()));
        } catch (IOException e) {
            log.error("feign.IOException", e);
        }
        return new ServiceException(MessageCode.builder(ExceptionCodeEnum.ERROR));
    }
}

Upvotes: 11

Views: 13310

Answers (2)

Udhayakumar Baskaran
Udhayakumar Baskaran

Reputation: 131

Logger / System.out.println / IDE Debug mode

Don't use any of the above feature before get the response.body()

If you use any of the above feature to print / log / view your response object then it will process the response.body() internally and close the InputStream. So in this case you will get Stream is closed error.

To fix this issue process the response.body() before the logger. Now you can check this by running your application but not in debug mode.

Sample code:

@Override
  public Exception decode(final String methodKey, final Response response) {
    final String error = getResponseBodyAsString(response.body());
    LOGGER.error("{} failed with response {}", methodKey, response);
    return new ServiceException("Request failed with status: " + response.status()
                                                         + " and error: " + error);
  }

  private String getResponseBodyAsString(final Response.Body body) {
    try {
      return IOUtils.toString(body.asReader(StandardCharsets.UTF_8));
    } catch (final IOException e) {
      LOGGER.error("Failed to read the response body with error: ", e);
    }
    return null;
  }

Note: If you are in debug mode then your IDEA will process this response so even that case also you will get same error. So please don't check this in debug mode.

Upvotes: 10

arkadio
arkadio

Reputation: 389

I went through this nightmare and it was all the IDE's fault.

The breakpoint in the debug mode was over/before the response.body().asReader causing the stream to close.

Simply started debugging after reading the body and everything went fine.

Upvotes: 28

Related Questions