@@ -148,50 +148,65 @@ pub async fn check_success(
148148 return Ok ( response) ;
149149 }
150150
151- let response = response. try_into_raw_response ( ) . await ?;
151+ let raw_response = response. try_into_raw_response ( ) . await ?;
152152
153153 // If there's no body, we can't extract any more information.
154- if response. body ( ) . is_empty ( ) {
155- let code = response. headers ( ) . get_optional_str ( & ERROR_CODE ) ;
156- let error_kind = ErrorKind :: http_response ( status, code. map ( str:: to_owned) ) ;
154+ if raw_response. body ( ) . is_empty ( ) {
155+ let error_code = raw_response
156+ . headers ( )
157+ . get_optional_str ( & ERROR_CODE )
158+ . map ( str:: to_owned) ;
159+ let error_kind = ErrorKind :: HttpResponse {
160+ status,
161+ error_code,
162+ raw_response : Some ( Box :: new ( raw_response) ) ,
163+ } ;
157164 return Err ( Error :: with_message ( error_kind, status. to_string ( ) ) ) ;
158165 }
159166 let internal_response =
160- serde_json:: de:: from_slice :: < ErrorResponseInternal > ( response. body ( ) ) . map_err ( Error :: from) ;
167+ serde_json:: de:: from_slice :: < ErrorResponseInternal > ( raw_response. body ( ) )
168+ . map_err ( Error :: from) ;
161169
162170 let internal_response = match internal_response {
163171 Ok ( r) => r,
164172 Err ( _) => {
165173 // If we can't parse the body, return a generic error with the status code and body
166- let code = response. headers ( ) . get_optional_str ( & ERROR_CODE ) ;
167- let error_kind = ErrorKind :: http_response (
174+ let error_code = raw_response
175+ . headers ( )
176+ . get_optional_str ( & ERROR_CODE )
177+ . map_or_else ( || raw_response. status ( ) . to_string ( ) , str:: to_owned) ;
178+ let message = str:: from_utf8 ( raw_response. body ( ) )
179+ . unwrap_or ( "(invalid utf-8 in body)" )
180+ . to_string ( ) ;
181+ let error_kind = ErrorKind :: HttpResponse {
168182 status,
169- Some ( code. map_or_else ( || response. status ( ) . to_string ( ) , str:: to_owned) ) ,
170- ) ;
183+ error_code : Some ( error_code) ,
184+ raw_response : Some ( Box :: new ( raw_response) ) ,
185+ } ;
171186 return Err ( Error :: with_message (
172187 error_kind,
173- format ! (
174- "{}: {}" ,
175- status,
176- str :: from_utf8( response. body( ) ) . unwrap_or( "(invalid utf-8 in body)" )
177- ) ,
188+ format ! ( "{}: {}" , status, message) ,
178189 ) ) ;
179190 }
180191 } ;
181192
182193 // We give priority to the error code in the header, and try the body version if it's not present.
183- let code = response. headers ( ) . get_optional_str ( & ERROR_CODE ) ;
184- let code = code. or ( internal_response. error . code ) ;
185-
186- let error_kind = ErrorKind :: http_response ( status, code. map ( str:: to_owned) ) ;
194+ let error_code = raw_response
195+ . headers ( )
196+ . get_optional_str ( & ERROR_CODE )
197+ . or ( internal_response. error . code )
198+ . map ( str:: to_owned) ;
199+ let message = internal_response
200+ . error
201+ . message
202+ . map_or_else ( || status. to_string ( ) , str:: to_owned) ;
203+ let error_kind = ErrorKind :: HttpResponse {
204+ status,
205+ error_code,
206+ raw_response : Some ( Box :: new ( raw_response) ) ,
207+ } ;
187208
188- Err ( Error :: with_message (
189- error_kind,
190- internal_response
191- . error
192- . message
193- . map_or_else ( || status. to_string ( ) , |m| m. to_owned ( ) ) ,
194- ) )
209+ Err ( Error :: with_message ( error_kind, message) )
195210}
196211
197212#[ cfg( test) ]
@@ -217,7 +232,7 @@ mod tests {
217232 ErrorKind :: HttpResponse {
218233 status: StatusCode :: ImATeapot ,
219234 error_code,
220- raw_response: None
235+ raw_response: Some ( _ ) ,
221236 }
222237 if error_code. as_deref( ) == Some ( "teapot" )
223238 ) ) ;
@@ -242,7 +257,7 @@ mod tests {
242257 ErrorKind :: HttpResponse {
243258 status: StatusCode :: ImATeapot ,
244259 error_code,
245- raw_response: None
260+ raw_response: Some ( _ ) ,
246261 }
247262 if error_code. as_deref( ) == Some ( "teapot" )
248263 ) ) ;
@@ -292,7 +307,7 @@ mod tests {
292307 ErrorKind :: HttpResponse {
293308 status: StatusCode :: Ok ,
294309 error_code,
295- raw_response: None
310+ raw_response: Some ( _ ) ,
296311 }
297312 if error_code. as_deref( ) == Some ( "teapot" )
298313 ) ) ;
@@ -306,14 +321,15 @@ mod tests {
306321
307322 let err = check_success ( response, None ) . await . unwrap_err ( ) ;
308323 let kind = err. kind ( ) ;
309- assert_eq ! (
310- * kind,
324+ assert ! ( matches !(
325+ kind,
311326 ErrorKind :: HttpResponse {
312327 status: StatusCode :: ImATeapot ,
313- error_code: Some ( "testError" . to_string ( ) ) ,
314- raw_response: None
328+ error_code,
329+ raw_response: Some ( _ ) ,
315330 }
316- ) ;
331+ if error_code. as_deref( ) == Some ( "testError" )
332+ ) ) ;
317333 }
318334
319335 #[ tokio:: test]
@@ -327,16 +343,23 @@ mod tests {
327343 ) ;
328344
329345 let err = check_success ( response, None ) . await . unwrap_err ( ) ;
330- let kind = err . kind ( ) ;
331- assert_eq ! (
332- * kind ,
333- ErrorKind :: HttpResponse {
334- status : StatusCode :: ImATeapot ,
335- error_code : Some ( "testError" . to_string ( ) ) ,
336- raw_response : None
337- }
338- ) ;
346+ let ErrorKind :: HttpResponse {
347+ status ,
348+ error_code : Some ( error_code ) ,
349+ raw_response : Some ( raw_response ) ,
350+ } = err . kind ( )
351+ else {
352+ panic ! ( "expected ErrorKind::HttpResponse" ) ;
353+ } ;
354+
339355 assert ! ( err. to_string( ) . contains( r#"{"json": "error"}"# ) ) ;
356+ assert_eq ! ( status, & StatusCode :: ImATeapot ) ;
357+ assert_eq ! ( error_code, "testError" ) ;
358+ assert_eq ! ( raw_response. status( ) , StatusCode :: ImATeapot ) ;
359+ assert_eq ! ( raw_response. headers( ) . iter( ) . count( ) , 1 ) ;
360+ assert ! (
361+ matches!( str :: from_utf8( raw_response. body( ) ) , Ok ( body) if body == r#"{"json": "error"}"# )
362+ ) ;
340363 }
341364
342365 #[ test]
0 commit comments