reqwest-middleware icon indicating copy to clipboard operation
reqwest-middleware copied to clipboard

Inconsistent `e.is_timeout()` After Upgrading to `reqwest-retry 0.7.0` and `reqwest-middleware 0.4.0`

Open lanyeeee opened this issue 2 months ago • 0 comments

Bug description

In my project, I am using reqwest-retry and reqwest-middleware to manage retries and timeouts. With reqwest-retry 0.6.1 and reqwest-middleware 0.3.3, timeout errors are correctly detected and I can add a custom message. However, after upgrading to reqwest-retry 0.7.0 and reqwest-middleware 0.4.0, the behavior of e.is_timeout() changes, causing inconsistency in how timeout errors are detected.

To Reproduce

Steps to reproduce the behavior:

  1. Use the following code
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use std::time::Duration;

#[tokio::main]
async fn main() {
    let retry_policy =
        ExponentialBackoff::builder().build_with_total_retry_duration(Duration::from_millis(1)); // make sure the timeout will be triggered

    let client = reqwest::ClientBuilder::new()
        .timeout(Duration::from_millis(1)) // make sure the timeout will be triggered
        .build()
        .unwrap();

    let client = reqwest_middleware::ClientBuilder::new(client)
        .with(RetryTransientMiddleware::new_with_policy(retry_policy))
        .build();

    let _ = client
        .get("https://www.google.com")
        .send()
        .await
        .map_err(|e| {
            println!("{:?}", e);
            if e.is_timeout() {
                println!("timeout");
                anyhow::Error::from(e).context("this is a timeout error, please check your network")
            } else {
                println!("not timeout");
                anyhow::Error::from(e)
            }
        });
}
  1. Compare the output between the following two sets of dependencies:
  • reqwest-retry 0.6.1 and reqwest-middleware 0.3.3
  • reqwest-retry 0.7.0 and reqwest-middleware 0.4.0
  1. The output of reqwest-retry 0.6.1 and reqwest-middleware 0.3.3:
Reqwest(reqwest::Error { kind: Request, url: "https://www.google.com/", source: TimedOut })
timeout

The output of reqwest-retry 0.7.0 and reqwest-middleware 0.4.0:

Middleware(error sending request for url (https://www.google.com/)

Caused by:
    operation timed out)
not timeout

Expected behavior

The e.is_timeout() function should behave consistently across both versions, allowing me to detect and handle timeout errors reliably. I expect that in both cases, the timeout error is identified and a user-friendly message is attached

Environment

  • OS: Windows 11
  • Rust version: 1.8.1
  • reqwest version: 0.12.9
  • reqwest-retry version: 0.7.0 or 0.6.1
  • reqwest-middleware version: 0.4.0 or 0.3.3

Additional context

The inconsistency with e.is_timeout() has caused issues in handling timeout errors. I would like to know if this change in behavior is intentional, and if so, how to correctly handle timeout errors in the new version, whether they come from Error::Middleware or Error::Reqwest. Can you give me a example?

lanyeeee avatar Dec 08 '24 09:12 lanyeeee