pub enum DialError {
InvalidAddress(String),
LocalSocket(String),
TlsConfig(String),
Transport(TransportError),
}Expand description
Why a QUIC dial did not produce a connection.
Separate from TransportError so the failures that happen before any
packet is sent — a bad address, a socket this machine would not open, a TLS
config it rejects — stay distinguishable from a peer that would not talk
to us. DialError::phase is that distinction as a value.
§Why there is a variant for a socket that would not open
A bind this machine refused is this side’s failure, and the type is what has
to say so. Folding it into InvalidAddress leaves
the message as the only thing telling the two apart — a substring test
wearing a type’s clothes. A consumer reading it that way recovers “this
machine has no IPv6 stack” only where the prose happens to contain could not bind, and files the result at whichever phase the caller named, which
for a single call to dial_quic_to is one word for four stages: a failed
v6 bind then publishes as a relay that failed a QUIC handshake, on a dial
where no packet left the machine.
The WebTransport arm offers no such substring to find. wtransport’s
endpoint constructor binds the socket too and its failure carries no could not bind in the message, so a TransportError there reaches
ErrorCause::Transport through a
draft’s ConnectionError, and is_local answers false for it — a
socket this machine could not open, filed against the peer. Both arms raise
this variant.
§Why it goes no further than this type
The fourteen From<DialError> for ConnectionError impls map this variant
onto ConnectionError::InvalidAddress, which is one of the variants the
facade reads as ErrorCause::Facade,
and with it is_local() == true — the right answer for a failure this side
decided. Splitting it further there would add public variants for a
distinction no caller on that path reads: a draft Connection is built by a
caller who named a host:port, not by one measuring which stage of a dial
died. The reader of the distinction is a caller of dial_quic_to, and it
reads it off this type directly.
Variants§
InvalidAddress(String)
addr is not a host:port this machine can resolve to a socket address.
LocalSocket(String)
A local socket could not be opened to send from.
Nothing about the target: the address is fine and this machine would not give us a socket to reach it with. The common cause by a distance is dialling a v6 address from a host or container with no IPv6 stack, which is a routine outcome for anything that enumerates both families of a dual-stack name — and a fact about the dialler, never about the peer.
TlsConfig(String)
The TLS client configuration could not be built.
Transport(TransportError)
The dial itself failed.
Implementations§
Source§impl DialError
impl DialError
Sourcepub fn phase(&self) -> DialPhase
pub fn phase(&self) -> DialPhase
Which stage of the dial this failure came from.
Total and structural: every variant answers, and no arm reads a message.
DialError::Transport splits on whether the transport error is the
typed TransportError::Handshake — which by construction exists only
where a peer answered — so everything else under it is the stack
declining to start, which is DialPhase::Connect.
Sourcepub fn is_local(&self) -> bool
pub fn is_local(&self) -> bool
Whether the dial failed before a packet left this machine.
True for everything but DialPhase::Handshake. The name matches
AnyConnectionError::is_local,
which answers the same question for everything after the dial, and it is
worth being exact about what each half of the answer buys:
trueis a guarantee. Nothing was sent, so the failure cannot be evidence about the peer, and anything that publishes it as such is publishing a finding that never happened.falseis not the opposite guarantee. It says the machine got as far as sending, and a handshake can still fail for reasons that are nobody’s fault in particular — a timeout, a network that dropped the packets. ReadTransportError::Handshake’s codes for what the peer actually said; this only says whether there was a peer to ask.
Trait Implementations§
Source§impl Error for DialError
impl Error for DialError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already carries, so
InvalidAddress, TlsConfig and Transport are what a caller has to
match on.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.
Source§impl From<DialError> for ConnectionError
impl From<DialError> for ConnectionError
Source§fn from(e: DialError) -> Self
fn from(e: DialError) -> Self
Maps a dial failure onto the variants this error already has, so a
caller matches InvalidAddress or TlsConfig.
§LocalSocket joins InvalidAddress, and that is the answer being kept
A socket this machine would not open has a variant of its own on
DialError, and it still arrives here.
Not laziness about the churn — InvalidAddress is one of the
variants the facade reads as
ErrorCause::Facade, which
is_local answers true for, and a failed bind is this side’s by
definition. Routing it to Transport would read better in prose and
would publish this machine’s missing IPv6 stack as the relay’s doing.
The phase is not lost, only unread on this path. A caller measuring
which stage of a dial died reads
DialError::phase off the dial
itself; a caller who arrived at this type named a host:port and asked
for a connection, not for a measurement, and a public variant here for
a distinction nothing on this path reads is churn with no reader, which
is why this impl stays flat.