Skip to content

Commit

Permalink
feat: Add reqwest response err helper
Browse files Browse the repository at this point in the history
  • Loading branch information
sirewix committed Jan 10, 2025
1 parent 288ef07 commit 77b970a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
6 changes: 5 additions & 1 deletion .github/workflows/rust-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ env:
# Defined CI jobs.
jobs:
check:
uses: famedly/backend-build-workflows/.github/workflows/rust-workflow.yml@v1
uses: famedly/backend-build-workflows/.github/workflows/rust-workflow.yml@main
secrets: inherit
with:
clippy_args: '--all-features'
test_args: '--all-features'
testcov_args: '--all-features'
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ resolver = "2"
publish = ["famedly"]

[dependencies]
reqwest = { version = "0.12.12", optional = true }
serde = { version = "1.0.210", features = ["derive"] }
thiserror = "1.0.64"
time = { version = "0.3.36", optional = true }
Expand All @@ -17,6 +18,7 @@ url = { version = "2.5.2", features = ["serde"] }
serde_json = "1.0.128"

[features]
reqwest = ["dep:reqwest"]
time = ["dep:time"]

[lints.rust]
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ mod base_url;
pub mod duration;
/// [serde::Deserialize] impl for [tracing::level_filters::LevelFilter]
mod level_filter;
#[cfg(feature = "reqwest")]
/// Helpers for [reqwest]
pub mod reqwest;

pub use base_url::{BaseUrl, BaseUrlParseError};
pub use level_filter::LevelFilter;
Expand Down
58 changes: 58 additions & 0 deletions src/reqwest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use std::{fmt, future::Future};

/// Wrapper around [reqwest::Error] with optional response body
#[derive(Debug, thiserror::Error)]
pub struct ReqwestErrorWithBody {
/// Error from [reqwest]
pub error: reqwest::Error,
/// Optional response body
pub body: Option<String>,
}

impl From<reqwest::Error> for ReqwestErrorWithBody {
fn from(error: reqwest::Error) -> ReqwestErrorWithBody {
Self { error, body: None }
}

Check warning on line 15 in src/reqwest.rs

View check run for this annotation

Codecov / codecov/patch

src/reqwest.rs#L13-L15

Added lines #L13 - L15 were not covered by tests
}

impl fmt::Display for ReqwestErrorWithBody {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} with body {}", self.error, self.body.as_deref().unwrap_or("<no body>"))
}

Check warning on line 21 in src/reqwest.rs

View check run for this annotation

Codecov / codecov/patch

src/reqwest.rs#L19-L21

Added lines #L19 - L21 were not covered by tests
}

/// An alternative to [reqwest::Resnpose::error_for_status] that also returns
/// optional response body
/// ```no_run
/// # use famedly_rust_utils::reqwest::*;
/// # async fn mk_req() -> Result<(), ReqwestErrorWithBody> {
/// reqwest::get("http://invalid.example")
/// .await?
/// .error_for_status_with_body()
/// .await?;
/// # Ok(())
/// # }
/// ```
pub trait ErrorForStatusWithBody {
// Using explicit `impl Future` syntax here instead of `async_fn_in_trait` to
// make it `Send`
#[allow(missing_docs)]
fn error_for_status_with_body(
self,
) -> impl Future<Output = Result<reqwest::Response, ReqwestErrorWithBody>> + Send;
}

impl ErrorForStatusWithBody for reqwest::Response {
#[allow(clippy::manual_async_fn)]
fn error_for_status_with_body(
self,
) -> impl Future<Output = Result<reqwest::Response, ReqwestErrorWithBody>> + Send {
async {
if let Err(error) = self.error_for_status_ref() {
Err(ReqwestErrorWithBody { error, body: self.text().await.ok() })

Check warning on line 52 in src/reqwest.rs

View check run for this annotation

Codecov / codecov/patch

src/reqwest.rs#L47-L52

Added lines #L47 - L52 were not covered by tests
} else {
Ok(self)

Check warning on line 54 in src/reqwest.rs

View check run for this annotation

Codecov / codecov/patch

src/reqwest.rs#L54

Added line #L54 was not covered by tests
}
}
}

Check warning on line 57 in src/reqwest.rs

View check run for this annotation

Codecov / codecov/patch

src/reqwest.rs#L56-L57

Added lines #L56 - L57 were not covered by tests
}

0 comments on commit 77b970a

Please sign in to comment.