16
16
17
17
package org .springframework .web .client ;
18
18
19
+ import java .io .ByteArrayInputStream ;
19
20
import java .io .IOException ;
21
+ import java .io .InputStreamReader ;
22
+ import java .io .Reader ;
23
+ import java .nio .CharBuffer ;
20
24
import java .nio .charset .Charset ;
25
+ import java .nio .charset .StandardCharsets ;
21
26
22
27
import org .springframework .http .HttpHeaders ;
23
28
import org .springframework .http .HttpStatus ;
24
29
import org .springframework .http .MediaType ;
25
30
import org .springframework .http .client .ClientHttpResponse ;
26
31
import org .springframework .lang .Nullable ;
27
32
import org .springframework .util .FileCopyUtils ;
33
+ import org .springframework .util .ObjectUtils ;
28
34
29
35
/**
30
36
* Spring's default implementation of the {@link ResponseErrorHandler} interface.
@@ -96,12 +102,51 @@ protected boolean hasError(int unknownStatusCode) {
96
102
public void handleError (ClientHttpResponse response ) throws IOException {
97
103
HttpStatus statusCode = HttpStatus .resolve (response .getRawStatusCode ());
98
104
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 (),
100
110
response .getHeaders (), getResponseBody (response ), getCharset (response ));
101
111
}
102
112
handleError (response , statusCode );
103
113
}
104
114
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
+
105
150
/**
106
151
* Handle the error in the given response with the given resolved status code.
107
152
* <p>The default implementation throws an {@link HttpClientErrorException}
@@ -118,13 +163,15 @@ protected void handleError(ClientHttpResponse response, HttpStatus statusCode) t
118
163
HttpHeaders headers = response .getHeaders ();
119
164
byte [] body = getResponseBody (response );
120
165
Charset charset = getCharset (response );
166
+ String message = getErrorMessage (statusCode .value (), statusText , body , charset );
167
+
121
168
switch (statusCode .series ()) {
122
169
case CLIENT_ERROR :
123
- throw HttpClientErrorException .create (statusCode , statusText , headers , body , charset );
170
+ throw HttpClientErrorException .create (message , statusCode , statusText , headers , body , charset );
124
171
case SERVER_ERROR :
125
- throw HttpServerErrorException .create (statusCode , statusText , headers , body , charset );
172
+ throw HttpServerErrorException .create (message , statusCode , statusText , headers , body , charset );
126
173
default :
127
- throw new UnknownHttpStatusCodeException (statusCode .value (), statusText , headers , body , charset );
174
+ throw new UnknownHttpStatusCodeException (message , statusCode .value (), statusText , headers , body , charset );
128
175
}
129
176
}
130
177
0 commit comments