diff --git a/reqwest-retry/src/retryable.rs b/reqwest-retry/src/retryable.rs index a904e1c..a19f215 100644 --- a/reqwest-retry/src/retryable.rs +++ b/reqwest-retry/src/retryable.rs @@ -50,7 +50,12 @@ impl Retryable { { Some(Retryable::Fatal) } else if error.is_request() { + // It seems that hyper::Error(IncompleteMessage) is not correctly handled by reqwest. + // Here we check if the Reqwest error was originated by hyper and map it consistently. if let Some(hyper_error) = get_source_error_type::(&error) { + // The hyper::Error(IncompleteMessage) is raised if the HTTP response is well formatted but does not contain all the bytes. + // This can happen when the server has started sending back the response but the connection is cut halfway thorugh. + // We can safely retry the call, hence marking this error as [`Retryable::Transient`]. if hyper_error.is_incomplete_message() { Some(Retryable::Transient) } else { @@ -77,6 +82,7 @@ impl From<&reqwest::Error> for Retryable { } } +/// Downcasts the given [`err`] source into [`T`]. fn get_source_error_type( err: &dyn std::error::Error, ) -> Option<&T> {