Skip to content

Commit e6a6580

Browse files
committed
Merge pull request #1956
Closes gh-1956
2 parents 8bb165e + 04aa3d0 commit e6a6580

File tree

7 files changed

+338
-68
lines changed

7 files changed

+338
-68
lines changed

spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java

+51-4
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@
1616

1717
package org.springframework.web.client;
1818

19+
import java.io.ByteArrayInputStream;
1920
import java.io.IOException;
21+
import java.io.InputStreamReader;
22+
import java.io.Reader;
23+
import java.nio.CharBuffer;
2024
import java.nio.charset.Charset;
25+
import java.nio.charset.StandardCharsets;
2126

2227
import org.springframework.http.HttpHeaders;
2328
import org.springframework.http.HttpStatus;
2429
import org.springframework.http.MediaType;
2530
import org.springframework.http.client.ClientHttpResponse;
2631
import org.springframework.lang.Nullable;
2732
import org.springframework.util.FileCopyUtils;
33+
import org.springframework.util.ObjectUtils;
2834

2935
/**
3036
* Spring's default implementation of the {@link ResponseErrorHandler} interface.
@@ -96,12 +102,51 @@ protected boolean hasError(int unknownStatusCode) {
96102
public void handleError(ClientHttpResponse response) throws IOException {
97103
HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
98104
if (statusCode == null) {
99-
throw new UnknownHttpStatusCodeException(response.getRawStatusCode(), response.getStatusText(),
105+
String message = getErrorMessage(
106+
response.getRawStatusCode(), response.getStatusText(),
107+
getResponseBody(response), getCharset(response));
108+
throw new UnknownHttpStatusCodeException(message,
109+
response.getRawStatusCode(), response.getStatusText(),
100110
response.getHeaders(), getResponseBody(response), getCharset(response));
101111
}
102112
handleError(response, statusCode);
103113
}
104114

115+
/**
116+
* Return error message with details from the response body, possibly truncated:
117+
* <pre>
118+
* 404 Not Found: [{'id': 123, 'message': 'my very long... (500 bytes)]
119+
* </pre>
120+
*/
121+
private String getErrorMessage(
122+
int rawStatusCode, String statusText, @Nullable byte[] responseBody, @Nullable Charset charset) {
123+
124+
String preface = rawStatusCode + " " + statusText + ": ";
125+
if (ObjectUtils.isEmpty(responseBody)) {
126+
return preface + "[no body]";
127+
}
128+
129+
charset = charset == null ? StandardCharsets.UTF_8 : charset;
130+
int maxChars = 200;
131+
132+
if (responseBody.length < maxChars * 2) {
133+
return preface + "[" + new String(responseBody, charset) + "]";
134+
}
135+
136+
try {
137+
Reader reader = new InputStreamReader(new ByteArrayInputStream(responseBody), charset);
138+
CharBuffer buffer = CharBuffer.allocate(maxChars);
139+
reader.read(buffer);
140+
reader.close();
141+
buffer.flip();
142+
return preface + "[" + buffer.toString() + "... (" + responseBody.length + " bytes)]";
143+
}
144+
catch (IOException ex) {
145+
// should never happen
146+
throw new IllegalStateException(ex);
147+
}
148+
}
149+
105150
/**
106151
* Handle the error in the given response with the given resolved status code.
107152
* <p>The default implementation throws an {@link HttpClientErrorException}
@@ -118,13 +163,15 @@ protected void handleError(ClientHttpResponse response, HttpStatus statusCode) t
118163
HttpHeaders headers = response.getHeaders();
119164
byte[] body = getResponseBody(response);
120165
Charset charset = getCharset(response);
166+
String message = getErrorMessage(statusCode.value(), statusText, body, charset);
167+
121168
switch (statusCode.series()) {
122169
case CLIENT_ERROR:
123-
throw HttpClientErrorException.create(statusCode, statusText, headers, body, charset);
170+
throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset);
124171
case SERVER_ERROR:
125-
throw HttpServerErrorException.create(statusCode, statusText, headers, body, charset);
172+
throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset);
126173
default:
127-
throw new UnknownHttpStatusCodeException(statusCode.value(), statusText, headers, body, charset);
174+
throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset);
128175
}
129176
}
130177

0 commit comments

Comments
 (0)