|
14 | 14 | // KIND, either express or implied. See the License for the
|
15 | 15 | // specific language governing permissions and limitations
|
16 | 16 | // under the License.
|
17 |
| - |
18 | 17 | use std::collections::HashMap;
|
19 | 18 | use std::fmt::{Debug, Formatter};
|
20 | 19 | use std::sync::Mutex;
|
21 | 20 |
|
22 | 21 | use iceberg::{Error, ErrorKind, Result};
|
| 22 | +use log::debug; |
23 | 23 | use reqwest::header::HeaderMap;
|
24 | 24 | use reqwest::{Client, IntoUrl, Method, Request, RequestBuilder, Response};
|
25 | 25 | use serde::de::DeserializeOwned;
|
@@ -236,36 +236,44 @@ impl HttpClient {
|
236 | 236 |
|
237 | 237 | let resp = self.client.execute(request).await?;
|
238 | 238 |
|
239 |
| - if resp.status().as_u16() == SUCCESS_CODE { |
240 |
| - let text = resp |
241 |
| - .bytes() |
242 |
| - .await |
243 |
| - .map_err(|err| err.with_url(url.clone()))?; |
244 |
| - Ok(serde_json::from_slice::<R>(&text).map_err(|e| { |
| 239 | + // Capture the status code before consuming the response body. |
| 240 | + let status = resp.status(); |
| 241 | + |
| 242 | + // Consume the response body once and store the bytes. |
| 243 | + let bytes = resp |
| 244 | + .bytes() |
| 245 | + .await |
| 246 | + .map_err(|err| err.with_url(url.clone()))?; |
| 247 | + |
| 248 | + // Optionally, log the response. |
| 249 | + debug!( |
| 250 | + "Response from {} {}: {}", |
| 251 | + method, |
| 252 | + url, |
| 253 | + String::from_utf8_lossy(&bytes) |
| 254 | + ); |
| 255 | + |
| 256 | + if status.as_u16() == SUCCESS_CODE { |
| 257 | + Ok(serde_json::from_slice::<R>(&bytes).map_err(|e| { |
245 | 258 | Error::new(
|
246 | 259 | ErrorKind::Unexpected,
|
247 | 260 | "Failed to parse response from rest catalog server!",
|
248 | 261 | )
|
249 | 262 | .with_context("method", method.to_string())
|
250 | 263 | .with_context("url", url.to_string())
|
251 |
| - .with_context("json", String::from_utf8_lossy(&text)) |
| 264 | + .with_context("json", String::from_utf8_lossy(&bytes)) |
252 | 265 | .with_source(e)
|
253 | 266 | })?)
|
254 | 267 | } else {
|
255 |
| - let code = resp.status(); |
256 |
| - let text = resp |
257 |
| - .bytes() |
258 |
| - .await |
259 |
| - .map_err(|err| err.with_url(url.clone()))?; |
260 |
| - let e = serde_json::from_slice::<E>(&text).map_err(|e| { |
| 268 | + let e = serde_json::from_slice::<E>(&bytes).map_err(|e| { |
261 | 269 | Error::new(
|
262 | 270 | ErrorKind::Unexpected,
|
263 | 271 | "Failed to parse response from rest catalog server!",
|
264 | 272 | )
|
265 |
| - .with_context("code", code.to_string()) |
| 273 | + .with_context("code", status.to_string()) |
266 | 274 | .with_context("method", method.to_string())
|
267 | 275 | .with_context("url", url.to_string())
|
268 |
| - .with_context("json", String::from_utf8_lossy(&text)) |
| 276 | + .with_context("json", String::from_utf8_lossy(&bytes)) |
269 | 277 | .with_source(e)
|
270 | 278 | })?;
|
271 | 279 | Err(e.into())
|
|
0 commit comments