Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc and Error::Other for bespoke connector chains #1032

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

* Improved errors and doc for bespoke transports (#1032)

# 3.0.8

* Fix incorrect parsing bug "missing http version" (#1026)
Expand Down
27 changes: 26 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ pub enum Error {
InvalidProxyUrl,

/// A connection failed.
///
/// This is a fallback error when there is no other explanation as to
/// why a connector chain didn't produce a connection. The idea is that the connector
/// chain would return some other [`Error`] rather than rely om this value.
///
/// Typically bespoke connector chains should, as far as possible, map their underlying
/// errors to [`Error::Io`] and use the [`io::ErrorKind`] to provide a reason.
///
/// A bespoke chain is allowed to map to this value, but that provides very little
/// information to the user as to why the connection failed. One way to mitigate that
/// would be to rely on the `log` crate to provide additional information.
ConnectionFailed,

/// A send body (Such as `&str`) is larger than the `content-length` header.
Expand Down Expand Up @@ -148,7 +159,20 @@ pub enum Error {
/// This typically indicates a fault in bespoke `Connector` chains.
TlsRequired,

/// hoot made no progress and there is no more input to read.
/// Some other error occured.
///
/// This is an escape hatch for bespoke connector chains having errors that don't naturally
/// map to any other error. For connector chains we recommend:
///
/// 1. Map to [`Error::Io`] as far as possible.
/// 2. Map to other [`Error`] where reasonable.
/// 3. Fall back on [`Error::Other`].
/// 4. As a last resort [`Error::ConnectionFailed`].
///
/// ureq does not produce this error using the default connectors.
Other(Box<dyn std::error::Error + Send + Sync>),

/// ureq-proto made no progress and there is no more input to read.
///
/// We should never see this value.
#[doc(hidden)]
Expand Down Expand Up @@ -237,6 +261,7 @@ impl fmt::Display for Error {
Error::Json(v) => write!(f, "json: {}", v),
Error::ConnectProxyFailed(v) => write!(f, "CONNECT proxy failed: {}", v),
Error::TlsRequired => write!(f, "TLS required, but transport is unsecured"),
Error::Other(v) => write!(f, "other: {}", v),
Error::BodyStalled => write!(f, "body data reading stalled"),
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,5 +1207,10 @@ pub(crate) mod test {
let response = post("https://yaz").send(&data).unwrap();
let owned_reader = response.into_parts().1.into_reader();
is_sync(owned_reader);

let err = Error::HostNotFound;
is_send(err);
let err = Error::HostNotFound;
is_sync(err);
}
}
9 changes: 9 additions & 0 deletions src/unversioned/transport/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ pub use crate::timings::NextTimeout;
///
/// The built-in [`DefaultConnector`] provides SOCKS, TCP sockets and TLS wrapping.
///
/// # Errors
///
/// When writing a bespoke connector chain we recommend handling errors like this:
///
/// 1. Map to [`Error::Io`] as far as possible.
/// 2. Map to any other [`Error`] where reasonable.
/// 3. Fall back on [`Error::Other`] preserving the original error.
/// 4. As a last resort [`Error::ConnectionFailed`] + logging.
///
/// # Example
///
/// ```
Expand Down
Loading