From bac658200b747da4023f7eb68ccbed8edb8191f8 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 29 Oct 2021 11:57:07 +0200 Subject: [PATCH 1/4] Retry on 5xx, error on 4xx --- .../policies/retry_policies/retry_policy.rs | 34 +++++++++++++------ sdk/core/src/response.rs | 10 ++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/sdk/core/src/policies/retry_policies/retry_policy.rs b/sdk/core/src/policies/retry_policies/retry_policy.rs index f6e3872f5a..3e97470753 100644 --- a/sdk/core/src/policies/retry_policies/retry_policy.rs +++ b/sdk/core/src/policies/retry_policies/retry_policy.rs @@ -2,6 +2,7 @@ use crate::policies::{Policy, PolicyResult, Request, Response}; use crate::sleep::sleep; use crate::PipelineContext; use chrono::{DateTime, Local}; +use http::StatusCode; use std::sync::Arc; use std::time::Duration; @@ -26,19 +27,32 @@ where let mut retry_count = 0; loop { - match next[0].send(ctx, request, &next[1..]).await { - Ok(response) => return Ok(response), - Err(error) => { - log::error!("Error occurred when making request: {}", error); - if self.is_expired(&mut first_retry_time, retry_count) { - return Err(error); - } else { - retry_count += 1; - - sleep(self.sleep_duration(retry_count)).await; + let error = match next[0].send(ctx, request, &next[1..]).await { + Ok(response) => { + let status = response.status(); + if status.as_u16() < 400 { + // Successful status code + return Ok(response); + } else if status.as_u16() < 500 { + // Server returned a client caused error + return Ok(response.validate(StatusCode::OK).await?); } + // Server returned an internal error, try again + log::error!("server returned error 500 status: {}", status); + Box::new(response.validate(StatusCode::OK).await.unwrap_err()) + } + Err(error) => { + log::error!("error occurred when making request: {}", error); + error } + }; + + if self.is_expired(&mut first_retry_time, retry_count) { + return Err(error); } + retry_count += 1; + + sleep(self.sleep_duration(retry_count)).await; } } } diff --git a/sdk/core/src/response.rs b/sdk/core/src/response.rs index 2d812cb1b9..0f26dc5b61 100644 --- a/sdk/core/src/response.rs +++ b/sdk/core/src/response.rs @@ -42,6 +42,16 @@ pub struct Response { body: PinnedStream, } +impl std::fmt::Debug for Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Response") + .field("status", &self.status) + .field("headers", &self.headers) + .field("body", &"") + .finish() + } +} + impl Response { pub(crate) fn new(status: StatusCode, headers: HeaderMap, body: PinnedStream) -> Self { Self { From 3d69a37849ed041da30ba3cd8fedf0a39cd0c4c9 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 29 Oct 2021 15:36:25 +0200 Subject: [PATCH 2/4] Onlyy retry on certain error statuses --- .../policies/retry_policies/retry_policy.rs | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/sdk/core/src/policies/retry_policies/retry_policy.rs b/sdk/core/src/policies/retry_policies/retry_policy.rs index 3e97470753..5816ffab9c 100644 --- a/sdk/core/src/policies/retry_policies/retry_policy.rs +++ b/sdk/core/src/policies/retry_policies/retry_policy.rs @@ -6,11 +6,32 @@ use http::StatusCode; use std::sync::Arc; use std::time::Duration; +/// A retry policy. +/// +/// All retry policies follow a similar pattern only differing in how +/// they determine if the retry has expired and for how long they should +/// sleep between retries. pub trait RetryPolicy { + /// Determine if no more retries should be performed. + /// + /// Must return true if no more retries should be attempted. fn is_expired(&self, first_retry_time: &mut Option>, retry_count: u32) -> bool; + /// Determine how long before the next retry should be attempted. fn sleep_duration(&self, retry_count: u32) -> Duration; } +/// The status codes where a retry should be attempted. +/// +/// On all other 4xx and 5xx status codes no retry is attempted. +const RETRY_STATUSES: &[StatusCode] = &[ + StatusCode::REQUEST_TIMEOUT, + StatusCode::TOO_MANY_REQUESTS, + StatusCode::INTERNAL_SERVER_ERROR, + StatusCode::BAD_GATEWAY, + StatusCode::SERVICE_UNAVAILABLE, + StatusCode::GATEWAY_TIMEOUT, +]; + #[async_trait::async_trait] impl Policy for T where @@ -33,12 +54,14 @@ where if status.as_u16() < 400 { // Successful status code return Ok(response); - } else if status.as_u16() < 500 { - // Server returned a client caused error + } else if !RETRY_STATUSES.contains(&status) { + // Server didn't return a status we retry on return Ok(response.validate(StatusCode::OK).await?); } - // Server returned an internal error, try again - log::error!("server returned error 500 status: {}", status); + log::error!( + "server returned error status which requires retry: {}", + status + ); Box::new(response.validate(StatusCode::OK).await.unwrap_err()) } Err(error) => { From fe48dc637031aec9de9167f8798b6de835267224 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 29 Oct 2021 16:05:11 +0200 Subject: [PATCH 3/4] Only validate responses in the retry policy --- sdk/core/src/errors.rs | 38 +------------ sdk/core/src/http_client.rs | 40 ++------------ .../policies/retry_policies/retry_policy.rs | 14 +++-- sdk/core/src/response.rs | 53 ++++++++++++------- sdk/cosmos/src/clients/collection_client.rs | 8 --- sdk/cosmos/src/clients/cosmos_client.rs | 4 -- sdk/cosmos/src/clients/database_client.rs | 10 ---- sdk/cosmos/src/clients/document_client.rs | 2 - sdk/cosmos/src/clients/permission_client.rs | 8 --- sdk/cosmos/src/clients/user_client.rs | 8 --- ...reate_or_update_device_identity_builder.rs | 5 +- ...reate_or_update_module_identity_builder.rs | 5 +- .../data_lake/clients/file_system_client.rs | 2 - 13 files changed, 51 insertions(+), 146 deletions(-) diff --git a/sdk/core/src/errors.rs b/sdk/core/src/errors.rs index b12f2f138f..7008b4c61a 100644 --- a/sdk/core/src/errors.rs +++ b/sdk/core/src/errors.rs @@ -124,17 +124,8 @@ pub enum StreamError { pub enum HttpError { #[error("Failed to serialize request body as json: {0}")] BodySerializationError(serde_json::Error), - #[error( - "unexpected HTTP result (expected: {:?}, received: {:?}, body: {:?})", - expected, - received, - body - )] - UnexpectedStatusCode { - expected: Vec, - received: StatusCode, - body: String, - }, + #[error("HTTP error status (status: {:?}, body: {:?})", status, body)] + ErrorStatusCode { status: StatusCode, body: String }, #[error("UTF8 conversion error: {0}")] Utf8Error(#[from] std::str::Utf8Error), #[error("from UTF8 conversion error: {0}")] @@ -157,31 +148,6 @@ pub enum HttpError { StreamResetError(StreamError), } -impl HttpError { - pub fn new_unexpected_status_code( - expected: StatusCode, - received: StatusCode, - body: &str, - ) -> HttpError { - HttpError::UnexpectedStatusCode { - expected: vec![expected], - received, - body: body.to_owned(), - } - } - - pub fn new_multiple_unexpected_status_code( - allowed: Vec, - received: StatusCode, - body: &str, - ) -> HttpError { - HttpError::UnexpectedStatusCode { - expected: allowed, - received, - body: body.to_owned(), - } - } -} #[derive(Debug, PartialEq, thiserror::Error)] pub enum Not512ByteAlignedError { #[error("start range not 512-byte aligned: {0}")] diff --git a/sdk/core/src/http_client.rs b/sdk/core/src/http_client.rs index 8abfde0654..096e8dad64 100644 --- a/sdk/core/src/http_client.rs +++ b/sdk/core/src/http_client.rs @@ -41,43 +41,13 @@ pub trait HttpClient: Send + Sync + std::fmt::Debug { async fn execute_request_check_status( &self, request: Request, - expected_status: StatusCode, + _expected_status: StatusCode, ) -> Result, HttpError> { let response = self.execute_request(request).await?; - if expected_status != response.status() { - Err(HttpError::new_unexpected_status_code( - expected_status, - response.status(), - std::str::from_utf8(response.body())?, - )) - } else { - Ok(response) - } - } - - async fn execute_request_check_statuses( - &self, - request: Request, - expected_statuses: &[StatusCode], - ) -> Result, HttpError> { - let response = self.execute_request(request).await?; - if !expected_statuses - .iter() - .any(|expected_status| *expected_status == response.status()) - { - if expected_statuses.len() == 1 { - Err(HttpError::new_unexpected_status_code( - expected_statuses[0], - response.status(), - std::str::from_utf8(response.body())?, - )) - } else { - Err(HttpError::new_multiple_unexpected_status_code( - expected_statuses.to_vec(), - response.status(), - std::str::from_utf8(response.body())?, - )) - } + let status = response.status(); + if (200..400).contains(&status.as_u16()) { + let body = std::str::from_utf8(response.body())?.to_owned(); + Err(crate::HttpError::ErrorStatusCode { status, body }) } else { Ok(response) } diff --git a/sdk/core/src/policies/retry_policies/retry_policy.rs b/sdk/core/src/policies/retry_policies/retry_policy.rs index 5816ffab9c..89b0183ed7 100644 --- a/sdk/core/src/policies/retry_policies/retry_policy.rs +++ b/sdk/core/src/policies/retry_policies/retry_policy.rs @@ -1,6 +1,6 @@ use crate::policies::{Policy, PolicyResult, Request, Response}; use crate::sleep::sleep; -use crate::PipelineContext; +use crate::{HttpError, PipelineContext}; use chrono::{DateTime, Local}; use http::StatusCode; use std::sync::Arc; @@ -54,15 +54,19 @@ where if status.as_u16() < 400 { // Successful status code return Ok(response); - } else if !RETRY_STATUSES.contains(&status) { - // Server didn't return a status we retry on - return Ok(response.validate(StatusCode::OK).await?); + } + + let body = response.into_body_string().await; + let error = Box::new(HttpError::ErrorStatusCode { status, body }); + if !RETRY_STATUSES.contains(&status) { + // Server didn't return a status we retry on so return early + return Err(error); } log::error!( "server returned error status which requires retry: {}", status ); - Box::new(response.validate(StatusCode::OK).await.unwrap_err()) + error } Err(error) => { log::error!("error occurred when making request: {}", error); diff --git a/sdk/core/src/response.rs b/sdk/core/src/response.rs index 0f26dc5b61..2aeda4a781 100644 --- a/sdk/core/src/response.rs +++ b/sdk/core/src/response.rs @@ -36,22 +36,13 @@ impl ResponseBuilder { } } +// An HTTP Response pub struct Response { status: StatusCode, headers: HeaderMap, body: PinnedStream, } -impl std::fmt::Debug for Response { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Response") - .field("status", &self.status) - .field("headers", &self.headers) - .field("body", &"") - .finish() - } -} - impl Response { pub(crate) fn new(status: StatusCode, headers: HeaderMap, body: PinnedStream) -> Self { Self { @@ -73,21 +64,29 @@ impl Response { (self.status, self.headers, self.body) } - pub async fn validate(self, expected_status: StatusCode) -> Result { + pub async fn validate(self) -> Result { let status = self.status(); - if expected_status != status { - let body = collect_pinned_stream(self.body) - .await - .unwrap_or_else(|_| Bytes::from_static("".as_bytes())); - Err(crate::HttpError::new_unexpected_status_code( - expected_status, - status, - std::str::from_utf8(&body as &[u8]).unwrap_or(""), - )) + if (200..400).contains(&status.as_u16()) { + let body = self.into_body_string().await; + Err(crate::HttpError::ErrorStatusCode { status, body }) } else { Ok(self) } } + + pub async fn into_body_string(self) -> String { + pinned_stream_into_utf8_string(self.body).await + } +} + +impl std::fmt::Debug for Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Response") + .field("status", &self.status) + .field("headers", &self.headers) + .field("body", &"") + .finish() + } } /// Convenience function that transforms a `PinnedStream` in a `bytes::Bytes` struct by collecting all the chunks. It consumes the response stream. @@ -102,6 +101,20 @@ pub async fn collect_pinned_stream(mut pinned_stream: PinnedStream) -> Result String { + let body = collect_pinned_stream(stream) + .await + .unwrap_or_else(|_| Bytes::from_static("".as_bytes())); + let body = std::str::from_utf8(&body) + .unwrap_or("") + .to_owned(); + body +} + impl From for Response { fn from(bytes_response: BytesResponse) -> Self { let (status, headers, body) = bytes_response.deconstruct(); diff --git a/sdk/cosmos/src/clients/collection_client.rs b/sdk/cosmos/src/clients/collection_client.rs index da5392714f..535a00a8eb 100644 --- a/sdk/cosmos/src/clients/collection_client.rs +++ b/sdk/cosmos/src/clients/collection_client.rs @@ -58,8 +58,6 @@ impl CollectionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(GetCollectionResponse::try_from(response).await?) @@ -80,8 +78,6 @@ impl CollectionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::NO_CONTENT) .await?; Ok(DeleteCollectionResponse::try_from(response).await?) @@ -102,8 +98,6 @@ impl CollectionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(ReplaceCollectionResponse::try_from(response).await?) @@ -128,8 +122,6 @@ impl CollectionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(CreateDocumentResponse::try_from(response).await?) diff --git a/sdk/cosmos/src/clients/cosmos_client.rs b/sdk/cosmos/src/clients/cosmos_client.rs index f6d1b4c722..d5e477fa69 100644 --- a/sdk/cosmos/src/clients/cosmos_client.rs +++ b/sdk/cosmos/src/clients/cosmos_client.rs @@ -191,8 +191,6 @@ impl CosmosClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(CreateDatabaseResponse::try_from(response).await?) @@ -239,7 +237,6 @@ impl CosmosClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListDatabasesResponse::try_from(response).await } @@ -256,7 +253,6 @@ impl CosmosClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListDatabasesResponse::try_from(response).await } State::Done => return None, diff --git a/sdk/cosmos/src/clients/database_client.rs b/sdk/cosmos/src/clients/database_client.rs index a715b99479..88ea62f752 100644 --- a/sdk/cosmos/src/clients/database_client.rs +++ b/sdk/cosmos/src/clients/database_client.rs @@ -72,8 +72,6 @@ impl DatabaseClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(GetDatabaseResponse::try_from(response).await?) @@ -94,8 +92,6 @@ impl DatabaseClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(DeleteDatabaseResponse::try_from(response).await?) @@ -127,7 +123,6 @@ impl DatabaseClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListCollectionsResponse::try_from(response).await } State::Continuation(continuation_token) => { @@ -146,7 +141,6 @@ impl DatabaseClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListCollectionsResponse::try_from(response).await } State::Done => return None, @@ -182,8 +176,6 @@ impl DatabaseClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(CreateCollectionResponse::try_from(response).await?) @@ -215,7 +207,6 @@ impl DatabaseClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListUsersResponse::try_from(response).await } State::Continuation(continuation_token) => { @@ -234,7 +225,6 @@ impl DatabaseClient { .send(&mut pipeline_context, &mut request) .await ); - let response = r#try!(response.validate(http::StatusCode::OK).await); ListUsersResponse::try_from(response).await } State::Done => return None, diff --git a/sdk/cosmos/src/clients/document_client.rs b/sdk/cosmos/src/clients/document_client.rs index 54d74d12bb..6f7ebe5e26 100644 --- a/sdk/cosmos/src/clients/document_client.rs +++ b/sdk/cosmos/src/clients/document_client.rs @@ -80,8 +80,6 @@ impl DocumentClient { .cosmos_client() .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; GetDocumentResponse::try_from(response).await diff --git a/sdk/cosmos/src/clients/permission_client.rs b/sdk/cosmos/src/clients/permission_client.rs index b30e423c78..36b2e7163e 100644 --- a/sdk/cosmos/src/clients/permission_client.rs +++ b/sdk/cosmos/src/clients/permission_client.rs @@ -67,8 +67,6 @@ impl PermissionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(PermissionResponse::try_from(response).await?) @@ -90,8 +88,6 @@ impl PermissionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(PermissionResponse::try_from(response).await?) @@ -112,8 +108,6 @@ impl PermissionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(PermissionResponse::try_from(response).await?) @@ -134,8 +128,6 @@ impl PermissionClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::NO_CONTENT) .await?; Ok(DeletePermissionResponse::try_from(response).await?) diff --git a/sdk/cosmos/src/clients/user_client.rs b/sdk/cosmos/src/clients/user_client.rs index 88473e65af..78fd63ad28 100644 --- a/sdk/cosmos/src/clients/user_client.rs +++ b/sdk/cosmos/src/clients/user_client.rs @@ -56,8 +56,6 @@ impl UserClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(UserResponse::try_from(response).await?) @@ -76,8 +74,6 @@ impl UserClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(UserResponse::try_from(response).await?) @@ -97,8 +93,6 @@ impl UserClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::OK) .await?; Ok(UserResponse::try_from(response).await?) @@ -117,8 +111,6 @@ impl UserClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::NO_CONTENT) .await?; Ok(DeleteUserResponse::try_from(response).await?) diff --git a/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs b/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs index eefb284173..399d3c817e 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs @@ -82,10 +82,7 @@ impl<'a> CreateOrUpdateDeviceIdentityBuilder<'a> { Ok(self .service_client .http_client() - .execute_request_check_statuses( - request, - &[http::StatusCode::OK, http::StatusCode::CREATED], - ) + .execute_request_check_status(request, http::StatusCode::OK) .await? .try_into()?) } diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs b/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs index 46b58e00a4..d3fbde2ca9 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs @@ -72,10 +72,7 @@ impl<'a> CreateOrUpdateModuleIdentityBuilder<'a> { Ok(self .service_client .http_client() - .execute_request_check_statuses( - request, - &[http::StatusCode::OK, http::StatusCode::CREATED], - ) + .execute_request_check_status(request, http::StatusCode::OK) .await? .try_into()?) } diff --git a/sdk/storage/src/data_lake/clients/file_system_client.rs b/sdk/storage/src/data_lake/clients/file_system_client.rs index bdcc035c90..e458e0c153 100644 --- a/sdk/storage/src/data_lake/clients/file_system_client.rs +++ b/sdk/storage/src/data_lake/clients/file_system_client.rs @@ -77,8 +77,6 @@ impl FileSystemClient { let response = self .pipeline() .send(&mut pipeline_context, &mut request) - .await? - .validate(http::StatusCode::CREATED) .await?; Ok(CreatePathResponse::try_from(response).await?) From 8796038937ac53f6b3dbbdc2240f1ca7f83118d6 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 29 Oct 2021 16:23:45 +0200 Subject: [PATCH 4/4] Fix inverted logic --- sdk/core/src/http_client.rs | 4 +-- .../policies/retry_policies/retry_policy.rs | 26 ++++++++++++++----- sdk/core/src/response.rs | 10 ------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/sdk/core/src/http_client.rs b/sdk/core/src/http_client.rs index 096e8dad64..8dae98bf9d 100644 --- a/sdk/core/src/http_client.rs +++ b/sdk/core/src/http_client.rs @@ -46,10 +46,10 @@ pub trait HttpClient: Send + Sync + std::fmt::Debug { let response = self.execute_request(request).await?; let status = response.status(); if (200..400).contains(&status.as_u16()) { + Ok(response) + } else { let body = std::str::from_utf8(response.body())?.to_owned(); Err(crate::HttpError::ErrorStatusCode { status, body }) - } else { - Ok(response) } } } diff --git a/sdk/core/src/policies/retry_policies/retry_policy.rs b/sdk/core/src/policies/retry_policies/retry_policy.rs index 89b0183ed7..c52f59bf18 100644 --- a/sdk/core/src/policies/retry_policies/retry_policy.rs +++ b/sdk/core/src/policies/retry_policies/retry_policy.rs @@ -49,27 +49,39 @@ where loop { let error = match next[0].send(ctx, request, &next[1..]).await { + Ok(response) if (200..400).contains(&response.status().as_u16()) => { + log::trace!( + "Succesful response. Request={:?} response={:?}", + request, + response + ); + // Successful status code + return Ok(response); + } Ok(response) => { + // Error status code let status = response.status(); - if status.as_u16() < 400 { - // Successful status code - return Ok(response); - } - let body = response.into_body_string().await; let error = Box::new(HttpError::ErrorStatusCode { status, body }); if !RETRY_STATUSES.contains(&status) { + log::error!( + "server returned error status which will not be retried: {}", + status + ); // Server didn't return a status we retry on so return early return Err(error); } - log::error!( + log::debug!( "server returned error status which requires retry: {}", status ); error } Err(error) => { - log::error!("error occurred when making request: {}", error); + log::debug!( + "error occurred when making request which will be retried: {}", + error + ); error } }; diff --git a/sdk/core/src/response.rs b/sdk/core/src/response.rs index 2aeda4a781..402177424b 100644 --- a/sdk/core/src/response.rs +++ b/sdk/core/src/response.rs @@ -64,16 +64,6 @@ impl Response { (self.status, self.headers, self.body) } - pub async fn validate(self) -> Result { - let status = self.status(); - if (200..400).contains(&status.as_u16()) { - let body = self.into_body_string().await; - Err(crate::HttpError::ErrorStatusCode { status, body }) - } else { - Ok(self) - } - } - pub async fn into_body_string(self) -> String { pinned_stream_into_utf8_string(self.body).await }