From eacaf844301b3a2b8a691d517f2e7190cfd7335b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 5 Mar 2025 16:43:56 +0000 Subject: [PATCH] add full response body to error message upon decoding failure (#5566) --- common/http-api-client/src/lib.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index 08c704897d..a8099ce111 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -210,6 +210,12 @@ pub enum HttpClientError { #[error("failed to resolve request. status: '{status}', additional error message: {error}")] EndpointFailure { status: StatusCode, error: E }, + #[error("failed to decode response body: {source} from {content}")] + ResponseDecodeFailure { + source: serde_json::Error, + content: String, + }, + #[cfg(target_arch = "wasm32")] #[error("the request has timed out")] RequestTimeout, @@ -866,19 +872,19 @@ where } if res.status().is_success() { - #[cfg(debug_assertions)] - { - let text = res.text().await.inspect_err(|err| { - tracing::error!("Couldn't even get response text: {err}"); - })?; - tracing::trace!("Result:\n{:#?}", text); - - serde_json::from_str(&text) - .map_err(|err| HttpClientError::GenericRequestFailure(err.to_string())) + // internally reqwest is first retrieving bytes and then performing parsing via serde_json + // (and similarly does the same thing for text()) + let full = res.bytes().await?; + match serde_json::from_slice(&full) { + Ok(data) => Ok(data), + Err(err) => { + let text = String::from_utf8_lossy(&full); + Err(HttpClientError::ResponseDecodeFailure { + source: err, + content: text.into_owned(), + }) + } } - - #[cfg(not(debug_assertions))] - Ok(res.json().await?) } else if res.status() == StatusCode::NOT_FOUND { Err(HttpClientError::NotFound) } else {