5

ErrorDecoder偽の例外をデコードするために実装しようとすると、ストリームresponse.body()が閉じていることがわかったので、ストリームを読み込んで文字列に変換しようとすると、スローされjava.io.IOException: stream is closedます。デコーダーの前に、ストリームアドバンスを閉じるために何もしなかったので、本当に混乱しています。

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));
    }
}
4

2 に答える 2

3

ロガー / System.out.println / IDE デバッグ モード

を取得する前に、上記の機能を使用しないでください。response.body()

上記の機能のいずれかを使用してresponseオブジェクトを印刷/ログ/表示すると、response.body()内部で処理され、InputStream. したがって、この場合、Stream is closedエラーが発生します。

この問題を修正するresponse.body()には、ロガーの前にプロセスを実行します。これで、デバッグ モードではなく、アプリケーションを実行してこれを確認できます。

サンプルコード:

@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;
  }

注: デバッグ モードの場合、IDEA はこの応答を処理するため、その場合でも同じエラーが発生します。したがって、デバッグ モードではこれをチェックしないでください。

于 2020-09-22T11:31:06.957 に答える