1717package org .springframework .web .client ;
1818
1919import java .io .IOException ;
20+ import java .net .URI ;
2021import java .nio .charset .Charset ;
2122
2223import org .springframework .http .HttpHeaders ;
24+ import org .springframework .http .HttpMethod ;
2325import org .springframework .http .HttpStatus ;
2426import org .springframework .http .MediaType ;
2527import org .springframework .http .client .ClientHttpResponse ;
2628import org .springframework .lang .Nullable ;
29+ import org .springframework .util .Assert ;
2730import org .springframework .util .FileCopyUtils ;
2831
2932/**
4346 */
4447public class DefaultResponseErrorHandler implements ResponseErrorHandler {
4548
49+ private HttpErrorDetailsExtractor httpErrorDetailsExtractor = new DefaultHttpErrorDetailsExtractor ();
50+
51+ /**
52+ * Set the error summary extractor.
53+ * <p>By default, DefaultResponseErrorHandler uses a {@link DefaultHttpErrorDetailsExtractor}.
54+ */
55+ public void setHttpErrorDetailsExtractor (HttpErrorDetailsExtractor httpErrorDetailsExtractor ) {
56+ Assert .notNull (httpErrorDetailsExtractor , "HttpErrorDetailsExtractor must not be null" );
57+ this .httpErrorDetailsExtractor = httpErrorDetailsExtractor ;
58+ }
59+
4660 /**
4761 * Delegates to {@link #hasError(HttpStatus)} (for a standard status enum value) or
4862 * {@link #hasError(int)} (for an unknown status code) with the response status code.
@@ -87,19 +101,31 @@ protected boolean hasError(int unknownStatusCode) {
87101 }
88102
89103 /**
90- * Delegates to {@link #handleError(ClientHttpResponse, HttpStatus)} with the
104+ * Delegates to {@link #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)} with the
91105 * response status code.
92106 * @throws UnknownHttpStatusCodeException in case of an unresolvable status code
93- * @see #handleError(ClientHttpResponse, HttpStatus)
107+ * @see #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)
94108 */
95109 @ Override
96110 public void handleError (ClientHttpResponse response ) throws IOException {
111+ handleError (null , null , response );
112+ }
113+
114+ /**
115+ * Delegates to {@link #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)} with the
116+ * response status code.
117+ * @throws UnknownHttpStatusCodeException in case of an unresolvable status code
118+ * @see #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)
119+ */
120+ @ Override
121+ public void handleError (URI url , HttpMethod method , ClientHttpResponse response ) throws IOException {
97122 HttpStatus statusCode = HttpStatus .resolve (response .getRawStatusCode ());
98123 if (statusCode == null ) {
99- throw new UnknownHttpStatusCodeException (response .getRawStatusCode (), response .getStatusText (),
100- response .getHeaders (), getResponseBody (response ), getCharset (response ));
124+ String message = httpErrorDetailsExtractor .getErrorDetails (response .getRawStatusCode (), response .getStatusText (), getResponseBody (response ), getCharset (response ), url , method );
125+ throw new UnknownHttpStatusCodeException (message , response .getRawStatusCode (), response .getStatusText (),
126+ response .getHeaders (), getResponseBody (response ), getCharset (response ), url , method );
101127 }
102- handleError (response , statusCode );
128+ handleError (url , method , response , statusCode );
103129 }
104130
105131 /**
@@ -114,17 +140,34 @@ public void handleError(ClientHttpResponse response) throws IOException {
114140 * @see HttpServerErrorException#create
115141 */
116142 protected void handleError (ClientHttpResponse response , HttpStatus statusCode ) throws IOException {
143+ handleError (null , null , response , statusCode );
144+ }
145+
146+ /**
147+ * Handle the error in the given response with the given resolved status code.
148+ * <p>This default implementation throws a {@link HttpClientErrorException} if the response status code
149+ * is {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}, a {@link HttpServerErrorException}
150+ * if it is {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR},
151+ * and a {@link RestClientException} in other cases.
152+ * @since 5.0
153+ */
154+ protected void handleError (@ Nullable URI url , @ Nullable HttpMethod method , ClientHttpResponse response ,
155+ HttpStatus statusCode ) throws IOException {
156+
117157 String statusText = response .getStatusText ();
118158 HttpHeaders headers = response .getHeaders ();
119159 byte [] body = getResponseBody (response );
120160 Charset charset = getCharset (response );
161+ String message = httpErrorDetailsExtractor .getErrorDetails (statusCode .value (), statusText , body , charset , url , method );
162+
121163 switch (statusCode .series ()) {
122164 case CLIENT_ERROR :
123- throw HttpClientErrorException .create (statusCode , statusText , headers , body , charset );
165+ throw HttpClientErrorException .create (message , statusCode , statusText , headers , body , charset , url , method );
124166 case SERVER_ERROR :
125- throw HttpServerErrorException .create (statusCode , statusText , headers , body , charset );
167+ throw HttpServerErrorException .create (message , statusCode , statusText , headers , body , charset , url , method );
126168 default :
127- throw new UnknownHttpStatusCodeException (statusCode .value (), statusText , headers , body , charset );
169+ throw new UnknownHttpStatusCodeException (message , statusCode .value (), statusText , headers , body ,
170+ charset , url , method );
128171 }
129172 }
130173
0 commit comments