Skip to content

Commit

Permalink
OrAnyStatus::or_any_status ergonomic helper
Browse files Browse the repository at this point in the history
Some users might prefer to handle all HTTP responses as Response
regardless of status code.
  • Loading branch information
algesten committed Jan 30, 2021
1 parent 0c467fe commit d627ef9
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
48 changes: 42 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,17 @@ use crate::Response;
/// ```
///
/// If you'd like to treat all status code errors as normal, successful responses,
/// you can use [Result::or_else](std::result::Result::or_else) like this:
/// you can use [OrAnyStatus::or_any_status] like this:
///
/// ```
/// use ureq::Error::Status;
/// # fn main() -> std::result::Result<(), ureq::Error> {
/// # fn main() -> std::result::Result<(), ureq::Transport> {
/// # ureq::is_test(true);
/// use ureq::OrAnyStatus;
///
/// let resp = ureq::get("http://example.com/")
/// .call()
/// .or_else(|e| match e {
/// Status(_, r) => Ok(r), // turn status errors into Ok Responses.
/// _ => Err(e),
/// })?;
/// .or_any_status()?;
/// # Ok(())
/// # }
/// ```
Expand All @@ -98,6 +97,43 @@ pub struct Transport {
response: Option<Response>,
}

/// Extension to [`Result<Response, Error>`] for handling all status codes as [`Response`].
pub trait OrAnyStatus {
/// Ergonomic helper for handling all status codes as [`Response`].
///
/// By default, ureq returns non-2xx responses as [`Error::Status`]. This
/// helper is for handling all responses as [`Response`], regardless
/// of status code.
///
/// ```
/// # ureq::is_test(true);
/// # fn main() -> Result<(), ureq::Transport> {
/// // Bring trait into context.
/// use ureq::OrAnyStatus;
///
/// let response = ureq::get("http://httpbin.org/status/500")
/// .call()
/// // Transport errors, such as DNS or connectivity problems
/// // must still be dealt with as `Err`.
/// .or_any_status()?;
///
/// assert_eq!(response.status(), 500);
/// # Ok(())
/// # }
/// ```
fn or_any_status(self) -> Result<Response, Transport>;
}

impl OrAnyStatus for Result<Response, Error> {
fn or_any_status(self) -> Result<Response, Transport> {
match self {
Ok(response) => Ok(response),
Err(Error::Status(_, response)) => Ok(response),
Err(Error::Transport(transport)) => Err(transport),
}
}
}

impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ mod testserver;

pub use crate::agent::Agent;
pub use crate::agent::AgentBuilder;
pub use crate::error::{Error, ErrorKind, Transport};
pub use crate::error::{Error, ErrorKind, OrAnyStatus, Transport};
pub use crate::header::Header;
pub use crate::proxy::Proxy;
pub use crate::request::Request;
Expand Down

0 comments on commit d627ef9

Please sign in to comment.