use reqwest::StatusCode;
use reqwest_retry::{Retryable, RetryableStrategy, default_on_request_failure};
#[derive(Default)]
pub struct LoggingRetryableStrategy {}
impl RetryableStrategy for LoggingRetryableStrategy {
fn handle(
&self,
res: &Result<reqwest::Response, reqwest_middleware::Error>,
) -> Option<Retryable> {
let result = match res {
Ok(resp) => on_request_success(resp),
Err(err) => default_on_request_failure(err),
};
if let Some(Retryable::Transient) = &result {
match res {
Ok(resp) => {
#[cfg(feature = "tracing")]
tracing::warn!(
"Retrying a transient error: response status code = {}",
resp.status()
)
}
Err(err) => {
#[cfg(feature = "tracing")]
tracing::warn!("Retrying a transient error: {err}")
}
}
}
result
}
}
fn on_request_success(success: &reqwest::Response) -> Option<Retryable> {
let status = success.status();
if status.is_success() {
None
} else if status.is_server_error() {
Some(Retryable::Transient)
} else if status == StatusCode::REQUEST_TIMEOUT {
Some(Retryable::Transient)
} else {
Some(Retryable::Fatal)
}
}