From 26af506441cff234d89f010d8ecb51e23c9690bc Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 13 Oct 2021 20:51:10 +0100 Subject: [PATCH] DefaultResponseErrorHandler shows full error details Closes gh-27552 --- .../core/log/LogFormatUtils.java | 16 +++++----- .../client/DefaultResponseErrorHandler.java | 29 +++++-------------- .../DefaultResponseErrorHandlerTests.java | 24 ++------------- 3 files changed, 16 insertions(+), 53 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java index 8ef04c71baf..e3ae033e9f2 100644 --- a/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java +++ b/spring-core/src/main/java/org/springframework/core/log/LogFormatUtils.java @@ -60,16 +60,11 @@ public abstract class LogFormatUtils { return ""; } String result; - if (value instanceof CharSequence) { - result = "\"" + value + "\""; + try { + result = value.toString(); } - else { - try { - result = value.toString(); - } - catch (Throwable ex) { - result = ex.toString(); - } + catch (Throwable ex) { + result = ex.toString(); } if (maxLength != -1) { result = (result.length() > maxLength ? result.substring(0, maxLength) + " (truncated)..." : result); @@ -77,6 +72,9 @@ public abstract class LogFormatUtils { if (replaceNewlines) { result = result.replace("\n", "").replace("\r", ""); } + if (value instanceof CharSequence) { + result = "\"" + result + "\""; + } return result; } diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index ddd3ab2ae5c..e8bda11ef03 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,11 @@ package org.springframework.web.client; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.springframework.core.log.LogFormatUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -135,29 +132,17 @@ public class DefaultResponseErrorHandler implements ResponseErrorHandler { int rawStatusCode, String statusText, @Nullable byte[] responseBody, @Nullable Charset charset) { String preface = rawStatusCode + " " + statusText + ": "; + if (ObjectUtils.isEmpty(responseBody)) { return preface + "[no body]"; } - charset = charset == null ? StandardCharsets.UTF_8 : charset; - int maxChars = 200; + charset = (charset != null ? charset : StandardCharsets.UTF_8); - if (responseBody.length < maxChars * 2) { - return preface + "[" + new String(responseBody, charset) + "]"; - } + String bodyText = new String(responseBody, charset); + bodyText = LogFormatUtils.formatValue(bodyText, -1, true); - try { - Reader reader = new InputStreamReader(new ByteArrayInputStream(responseBody), charset); - CharBuffer buffer = CharBuffer.allocate(maxChars); - reader.read(buffer); - reader.close(); - buffer.flip(); - return preface + "[" + buffer.toString() + "... (" + responseBody.length + " bytes)]"; - } - catch (IOException ex) { - // should never happen - throw new IllegalStateException(ex); - } + return preface + bodyText; } /** diff --git a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java index 1cb23587d7a..1ce0cfccd42 100644 --- a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,8 @@ package org.springframework.web.client; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.function.Function; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -75,25 +73,7 @@ public class DefaultResponseErrorHandlerTests { assertThatExceptionOfType(HttpClientErrorException.class) .isThrownBy(() -> handler.handleError(response)) .satisfies(ex -> assertThat(ex.getResponseHeaders()).isSameAs(headers)) - .satisfies(ex -> assertThat(ex.getMessage()).isEqualTo("404 Not Found: [Hello World]")); - } - - @Test - public void handleErrorWithLongBody() throws Exception { - - Function bodyGenerator = - size -> Flux.just("a").repeat(size-1).reduce((s, s2) -> s + s2).block(); - - given(response.getRawStatusCode()).willReturn(HttpStatus.NOT_FOUND.value()); - given(response.getStatusText()).willReturn("Not Found"); - given(response.getHeaders()).willReturn(new HttpHeaders()); - given(response.getBody()).willReturn( - new ByteArrayInputStream(bodyGenerator.apply(500).getBytes(StandardCharsets.UTF_8))); - - assertThatExceptionOfType(HttpClientErrorException.class) - .isThrownBy(() -> handler.handleError(response)) - .satisfies(ex -> assertThat(ex.getMessage()).isEqualTo( - "404 Not Found: [" + bodyGenerator.apply(200) + "... (500 bytes)]")); + .withMessage("404 Not Found: \"Hello World\""); } @Test