This is an automated email from the ASF dual-hosted git repository.
mneumann pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs-object-store.git
The following commit(s) were added to refs/heads/main by this push:
new d22f7f9 fix: missing 5xx error body when retry exhausted (#618)
d22f7f9 is described below
commit d22f7f91d576ab7b2a12750751a76d30018cb12d
Author: Jack Ye <[email protected]>
AuthorDate: Thu Mar 19 04:06:03 2026 -0700
fix: missing 5xx error body when retry exhausted (#618)
Co-authored-by: Andrew Lamb <[email protected]>
---
src/client/retry.rs | 53 +++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/src/client/retry.rs b/src/client/retry.rs
index b0e6b0c..45b73eb 100644
--- a/src/client/retry.rs
+++ b/src/client/retry.rs
@@ -410,15 +410,12 @@ impl RetryableRequest {
|| status == StatusCode::REQUEST_TIMEOUT
|| (self.retry_on_conflict && status ==
StatusCode::CONFLICT))
{
- let source = match status.is_client_error() {
- true => match r.into_body().text().await {
- Ok(body) => RequestError::Status {
- status,
- body: Some(body),
- },
- Err(e) => RequestError::Http(e),
+ let source = match r.into_body().text().await {
+ Ok(body) => RequestError::Status {
+ status,
+ body: Some(body),
},
- false => RequestError::Status { status, body:
None },
+ Err(e) => RequestError::Http(e),
};
return Err(self.err(source, ctx));
};
@@ -706,14 +703,16 @@ mod tests {
let e = do_request().await.unwrap_err();
assert!(
- e.to_string().contains(" after 2 retries, max_retries: 2,
retry_timeout: 1000s - Server returned non-2xx status code: 502 Bad Gateway"),
+ e.to_string().contains(" after 2 retries, max_retries: 2,
retry_timeout: 1000s - Server returned non-2xx status code: 502 Bad Gateway:
ignored"),
"{e}"
);
// verify e.source() is available as well for users who need
programmatic access
assert_eq!(
e.source().unwrap().to_string(),
- "Server returned non-2xx status code: 502 Bad Gateway: ",
+ "Server returned non-2xx status code: 502 Bad Gateway: ignored",
);
+ // verify body is accessible
+ assert_eq!(e.body(), Some("ignored"));
// Panic results in an incomplete message error in the client
mock.push_fn::<_, String>(|_| panic!());
@@ -847,6 +846,40 @@ mod tests {
mock.shutdown().await
}
+ #[tokio::test]
+ async fn test_503_error_body_captured() {
+ let mock = MockServer::new().await;
+
+ let retry = RetryConfig {
+ backoff: Default::default(),
+ max_retries: 0,
+ retry_timeout: Duration::from_secs(1000),
+ };
+
+ let client = HttpClient::new(Client::builder().build().unwrap());
+
+ // Test that 503 SlowDown body is captured for throttling detection
+ let slowdown_body = r#"<?xml version="1.0"
encoding="UTF-8"?><Error><Code>SlowDown</Code><Message>Please reduce your
request rate.</Message></Error>"#;
+ mock.push(
+ Response::builder()
+ .status(StatusCode::SERVICE_UNAVAILABLE)
+ .body(slowdown_body.to_string())
+ .unwrap(),
+ );
+
+ let e = client
+ .request(Method::GET, mock.url())
+ .send_retry(&retry)
+ .await
+ .unwrap_err();
+
+ assert_eq!(e.status().unwrap(), StatusCode::SERVICE_UNAVAILABLE);
+ assert_eq!(e.body(), Some(slowdown_body));
+ assert!(e.body().unwrap().contains("SlowDown"));
+
+ mock.shutdown().await
+ }
+
#[tokio::test]
#[expect(
deprecated,