Skip to content

Commit 3c0bb19

Browse files
experiments with n0-snafu
1 parent e32d32a commit 3c0bb19

File tree

5 files changed

+208
-48
lines changed

5 files changed

+208
-48
lines changed

Cargo.lock

Lines changed: 76 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

iroh-relay/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ webpki-roots = "0.26"
7070
data-encoding = "2.6.0"
7171
lru = "0.12"
7272
z32 = "1.0.3"
73+
snafu = { version = "0.8.5", features = ["rust_1_81"] }
74+
n0-snafu = { path = "../../n0-snafu" }
7375

7476
# server feature
7577
anyhow = { version = "1", optional = true }
@@ -129,7 +131,7 @@ tracing-test = "0.2.5"
129131
cfg_aliases = { version = "0.2" }
130132

131133
[features]
132-
default = ["metrics"]
134+
default = ["metrics", "server", "test-utils"]
133135
server = [
134136
"dep:anyhow",
135137
"dep:clap",

iroh-relay/src/client.rs

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use n0_future::{
1515
split::{split, SplitSink, SplitStream},
1616
time, Sink, Stream,
1717
};
18+
use snafu::{Backtrace, Snafu};
1819
#[cfg(any(test, feature = "test-utils"))]
1920
use tracing::warn;
2021
use tracing::{debug, event, trace, Level};
@@ -38,32 +39,84 @@ mod util;
3839

3940
/// Connection errors
4041
#[allow(missing_docs)]
41-
#[derive(Debug, thiserror::Error)]
42+
#[derive(Debug, Snafu)]
4243
#[non_exhaustive]
4344
pub enum ConnectError {
44-
#[error("Invalid URL for websocket {0}")]
45-
InvalidWebsocketUrl(Url),
46-
#[error("Invalid relay URL {0}")]
47-
InvalidRelayUrl(Url),
48-
#[error(transparent)]
49-
Websocket(#[from] tokio_tungstenite_wasm::Error),
50-
#[error(transparent)]
51-
Handshake(#[from] HandshakeError),
52-
#[error(transparent)]
53-
Dial(#[from] DialError),
54-
#[error("Unexpected status during upgrade: {0}")]
55-
UnexpectedUpgradeStatus(hyper::StatusCode),
56-
#[error("Failed to upgrade response")]
57-
Upgrade(#[source] hyper::Error),
58-
#[error("Invalid TLS servername")]
59-
InvalidTlsServername,
60-
#[error("No local address available")]
61-
NoLocalAddr,
62-
#[error("tls connection failed")]
63-
Tls(#[source] std::io::Error),
45+
#[snafu(display("Invalid URL for websocket: {url}"))]
46+
InvalidWebsocketUrl {
47+
url: Url,
48+
backtrace: Option<Backtrace>,
49+
#[snafu(implicit)]
50+
span_trace: n0_snafu::SpanTrace,
51+
},
52+
#[snafu(display("Invalid relay URL: {url}"))]
53+
InvalidRelayUrl {
54+
url: Url,
55+
backtrace: Option<Backtrace>,
56+
#[snafu(implicit)]
57+
span_trace: n0_snafu::SpanTrace,
58+
},
59+
#[snafu(transparent)]
60+
Websocket {
61+
source: tokio_tungstenite_wasm::Error,
62+
backtrace: Option<Backtrace>,
63+
#[snafu(implicit)]
64+
span_trace: n0_snafu::SpanTrace,
65+
},
66+
#[snafu(transparent)]
67+
Handshake {
68+
source: HandshakeError,
69+
backtrace: Option<Backtrace>,
70+
#[snafu(implicit)]
71+
span_trace: n0_snafu::SpanTrace,
72+
},
73+
#[snafu(transparent)]
74+
Dial {
75+
source: DialError,
76+
backtrace: Option<Backtrace>,
77+
#[snafu(implicit)]
78+
span_trace: n0_snafu::SpanTrace,
79+
},
80+
#[snafu(display("Unexpected status during upgrade: {code}"))]
81+
UnexpectedUpgradeStatus {
82+
code: hyper::StatusCode,
83+
backtrace: Option<Backtrace>,
84+
#[snafu(implicit)]
85+
span_trace: n0_snafu::SpanTrace,
86+
},
87+
#[snafu(display("Failed to upgrade response"))]
88+
Upgrade {
89+
source: hyper::Error,
90+
backtrace: Option<Backtrace>,
91+
#[snafu(implicit)]
92+
span_trace: n0_snafu::SpanTrace,
93+
},
94+
#[snafu(display("Invalid TLS servername"))]
95+
InvalidTlsServername {
96+
backtrace: Option<Backtrace>,
97+
#[snafu(implicit)]
98+
span_trace: n0_snafu::SpanTrace,
99+
},
100+
#[snafu(display("No local address available"))]
101+
NoLocalAddr {
102+
backtrace: Option<Backtrace>,
103+
#[snafu(implicit)]
104+
span_trace: n0_snafu::SpanTrace,
105+
},
106+
#[snafu(display("tls connection failed"))]
107+
Tls {
108+
source: std::io::Error,
109+
backtrace: Option<Backtrace>,
110+
#[snafu(implicit)]
111+
span_trace: n0_snafu::SpanTrace,
112+
},
64113
#[cfg(wasm_browser)]
65-
#[error("The relay protocol is not available in browsers")]
66-
RelayProtoNotAvailable,
114+
#[snafu(display("The relay protocol is not available in browsers"))]
115+
RelayProtoNotAvailable {
116+
backtrace: Option<Backtrace>,
117+
#[snafu(implicit)]
118+
span_trace: n0_snafu::SpanTrace,
119+
},
67120
}
68121

69122
/// Dialing errors
@@ -229,7 +282,12 @@ impl ClientBuilder {
229282
// We need to use the ws:// or wss:// schemes when connecting with websockets, though.
230283
dial_url
231284
.set_scheme(if self.use_tls() { "wss" } else { "ws" })
232-
.map_err(|_| ConnectError::InvalidWebsocketUrl(dial_url.clone()))?;
285+
.map_err(|_| {
286+
InvalidWebsocketUrlSnafu {
287+
url: dial_url.clone(),
288+
}
289+
.build()
290+
})?;
233291

234292
debug!(%dial_url, "Dialing relay by websocket");
235293

iroh-relay/src/client/connect_relay.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use hyper::{
2424
};
2525
use n0_future::{task, time};
2626
use rustls::client::Resumption;
27+
use snafu::ResultExt;
2728
use tokio::io::{AsyncRead, AsyncWrite};
2829
use tracing::{error, info_span, Instrument};
2930

@@ -64,21 +65,21 @@ impl ClientBuilder {
6465

6566
let local_addr = tcp_stream
6667
.local_addr()
67-
.map_err(|_| ConnectError::NoLocalAddr)?;
68+
.map_err(|_| NoLocalAddrSnafu.build())?;
6869

6970
debug!(server_addr = ?tcp_stream.peer_addr(), %local_addr, "TCP stream connected");
7071

7172
let response = if self.use_tls() {
7273
debug!("Starting TLS handshake");
7374
let hostname = self
7475
.tls_servername()
75-
.ok_or(ConnectError::InvalidTlsServername)?;
76+
.ok_or_else(|| InvalidTlsServernameSnafu.build())?;
7677

7778
let hostname = hostname.to_owned();
7879
let tls_stream = tls_connector
7980
.connect(hostname, tcp_stream)
8081
.await
81-
.map_err(ConnectError::Tls)?;
82+
.context(TlsSnafu)?;
8283
debug!("tls_connector connect success");
8384
Self::start_upgrade(tls_stream, url).await?
8485
} else {
@@ -87,13 +88,18 @@ impl ClientBuilder {
8788
};
8889

8990
if response.status() != hyper::StatusCode::SWITCHING_PROTOCOLS {
90-
return Err(ConnectError::UnexpectedUpgradeStatus(response.status()));
91+
UnexpectedUpgradeStatusSnafu {
92+
code: response.status(),
93+
}
94+
.fail()?;
9195
}
96+
let err = std::io::Error::new(std::io::ErrorKind::Other, "other".to_string());
97+
98+
Err(err).context(TlsSnafu)?;
99+
// NoLocalAddrSnafu.fail()?;
92100

93101
debug!("starting upgrade");
94-
let upgraded = hyper::upgrade::on(response)
95-
.await
96-
.map_err(ConnectError::Upgrade)?;
102+
let upgraded = hyper::upgrade::on(response).await.context(UpgradeSnafu)?;
97103

98104
debug!("connection upgraded");
99105
let conn = downcast_upgrade(upgraded).expect("must use TcpStream or client::TlsStream");
@@ -112,14 +118,18 @@ impl ClientBuilder {
112118
T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
113119
{
114120
use hyper_util::rt::TokioIo;
115-
let host_header_value = host_header_value(relay_url.clone())
116-
.ok_or_else(|| ConnectError::InvalidRelayUrl(relay_url.into()))?;
121+
let host_header_value = host_header_value(relay_url.clone()).ok_or_else(|| {
122+
InvalidRelayUrlSnafu {
123+
url: Url::from(relay_url),
124+
}
125+
.build()
126+
})?;
117127

118128
let io = TokioIo::new(io);
119129
let (mut request_sender, connection) = hyper::client::conn::http1::Builder::new()
120130
.handshake(io)
121131
.await
122-
.map_err(ConnectError::Upgrade)?;
132+
.context(UpgradeSnafu)?;
123133
task::spawn(
124134
// This task drives the HTTP exchange, completes once connection is upgraded.
125135
async move {
@@ -141,10 +151,7 @@ impl ClientBuilder {
141151
.header(HOST, host_header_value)
142152
.body(http_body_util::Empty::<hyper::body::Bytes>::new())
143153
.expect("fixed config");
144-
request_sender
145-
.send_request(req)
146-
.await
147-
.map_err(ConnectError::Upgrade)
154+
request_sender.send_request(req).await.context(UpgradeSnafu)
148155
}
149156

150157
fn tls_servername(&self) -> Option<rustls::pki_types::ServerName> {

0 commit comments

Comments
 (0)