added some comments

try-to-manage-hyper-incomplete-message
Alessandro Caprarelli 2021-10-13 17:08:46 +02:00
parent 161eb5a2af
commit fce3ea6d7e
1 changed files with 6 additions and 0 deletions

View File

@ -50,7 +50,12 @@ impl Retryable {
{ {
Some(Retryable::Fatal) Some(Retryable::Fatal)
} else if error.is_request() { } 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::<hyper::Error>(&error) { if let Some(hyper_error) = get_source_error_type::<hyper::Error>(&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() { if hyper_error.is_incomplete_message() {
Some(Retryable::Transient) Some(Retryable::Transient)
} else { } else {
@ -77,6 +82,7 @@ impl From<&reqwest::Error> for Retryable {
} }
} }
/// Downcasts the given [`err`] source into [`T`].
fn get_source_error_type<T: std::error::Error + 'static>( fn get_source_error_type<T: std::error::Error + 'static>(
err: &dyn std::error::Error, err: &dyn std::error::Error,
) -> Option<&T> { ) -> Option<&T> {