diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 120000 index 21a48da..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -reqwest-middleware/CHANGELOG.md \ No newline at end of file diff --git a/reqwest-middleware/CHANGELOG.md b/reqwest-middleware/CHANGELOG.md index ac38b2d..09e2f03 100644 --- a/reqwest-middleware/CHANGELOG.md +++ b/reqwest-middleware/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- `request_middleware::Error` is now a transparent error enum and doesn't add its own context anymore. + ## [0.3.3] - 2024-07-08 ### Added diff --git a/reqwest-middleware/src/error.rs b/reqwest-middleware/src/error.rs index 2ed8dfe..48285ec 100644 --- a/reqwest-middleware/src/error.rs +++ b/reqwest-middleware/src/error.rs @@ -6,10 +6,10 @@ pub type Result = std::result::Result; #[derive(Error, Debug)] pub enum Error { /// There was an error running some middleware - #[error("Middleware error: {0}")] + #[error(transparent)] Middleware(#[from] anyhow::Error), /// Error from the underlying reqwest client - #[error("Request error: {0}")] + #[error(transparent)] Reqwest(#[from] reqwest::Error), } diff --git a/reqwest-retry/CHANGELOG.md b/reqwest-retry/CHANGELOG.md index 1533a78..6d0be57 100644 --- a/reqwest-retry/CHANGELOG.md +++ b/reqwest-retry/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.6.0] ## [0.6.1] - 2024-08-08 @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Upgraded `retry-policies` to `0.4.0`. +- **Breaking Change** Errors are now reported as `RetryError` that adds the number of retries to the error chain if there were any. This changes the returned error types. ## [0.5.0] - 2024-04-10 diff --git a/reqwest-retry/Cargo.toml b/reqwest-retry/Cargo.toml index e4e90a4..d400558 100644 --- a/reqwest-retry/Cargo.toml +++ b/reqwest-retry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reqwest-retry" -version = "0.6.1" +version = "0.7.1" authors = ["Rodrigo Gryzinski "] edition = "2018" description = "Retry middleware for reqwest." @@ -18,6 +18,7 @@ futures = "0.3.0" http = "1.0" reqwest = { version = "0.12.0", default-features = false } retry-policies = "0.4" +thiserror = "1.0.61" tracing = "0.1.26" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/reqwest-retry/src/lib.rs b/reqwest-retry/src/lib.rs index d33ea1d..807ae9a 100644 --- a/reqwest-retry/src/lib.rs +++ b/reqwest-retry/src/lib.rs @@ -30,6 +30,7 @@ mod retryable; mod retryable_strategy; pub use retry_policies::{policies, Jitter, RetryDecision, RetryPolicy}; +use thiserror::Error; pub use middleware::RetryTransientMiddleware; pub use retryable::Retryable; @@ -37,3 +38,16 @@ pub use retryable_strategy::{ default_on_request_failure, default_on_request_success, DefaultRetryableStrategy, RetryableStrategy, }; + +/// Custom error type to attach the number of retries to the error message. +#[derive(Debug, Error)] +pub enum RetryError { + #[error("Request failed after {retries} retries")] + WithRetries { + retries: u32, + #[source] + err: reqwest_middleware::Error, + }, + #[error(transparent)] + Error(reqwest_middleware::Error), +} diff --git a/reqwest-retry/src/middleware.rs b/reqwest-retry/src/middleware.rs index e4f01d1..ec750bf 100644 --- a/reqwest-retry/src/middleware.rs +++ b/reqwest-retry/src/middleware.rs @@ -2,7 +2,7 @@ use std::time::{Duration, SystemTime}; use crate::retryable_strategy::RetryableStrategy; -use crate::{retryable::Retryable, retryable_strategy::DefaultRetryableStrategy}; +use crate::{retryable::Retryable, retryable_strategy::DefaultRetryableStrategy, RetryError}; use anyhow::anyhow; use http::Extensions; use reqwest::{Request, Response}; @@ -153,7 +153,7 @@ where // We classify the response which will return None if not // errors were returned. - break match self.retryable_strategy.handle(&result) { + match self.retryable_strategy.handle(&result) { Some(Retryable::Transient) => { // If the response failed and the error type was transient // we can safely try to retry the request. @@ -178,11 +178,24 @@ where n_past_retries += 1; continue; - } else { - result } } - Some(_) | None => result, + Some(_) | None => {} + }; + + // Report whether we failed with or without retries. + break if n_past_retries > 0 { + result.map_err(|err| { + Error::Middleware( + RetryError::WithRetries { + retries: n_past_retries, + err, + } + .into(), + ) + }) + } else { + result.map_err(|err| Error::Middleware(RetryError::Error(err).into())) }; } }