Skip to content

Commit 444c76b

Browse files
authored
refactor(iroh-relay,iroh): Slightly clean up staggered DNS errors (#3337)
## Description Instead of having two `StaggeredError` variants, let's just have one generic one. ## Breaking Changes ? see notes ## Notes & open questions We haven't cut a release since we've introduced the error types. So I guess any changes to the error types aren't breaking changes *yet*? ## Change checklist <!-- Remove any that are not relevant. --> - [x] Self-review.
1 parent 2b6c258 commit 444c76b

File tree

2 files changed

+40
-55
lines changed

2 files changed

+40
-55
lines changed

iroh-relay/src/dns.rs

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use n0_future::{
1313
StreamExt,
1414
};
1515
use nested_enum_utils::common_fields;
16-
use snafu::{Backtrace, OptionExt, Snafu};
16+
use snafu::{Backtrace, GenerateImplicitData, OptionExt, Snafu};
1717
use url::Url;
1818

1919
use crate::node_info::{LookupError, NodeInfo};
@@ -51,40 +51,30 @@ pub enum DnsError {
5151
},
5252
#[snafu(display("invalid DNS response: not a query for _iroh.z32encodedpubkey"))]
5353
InvalidResponse {},
54-
#[snafu(display("no calls succeeded: [{}]", errors.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("")))]
55-
Staggered { errors: Vec<DnsError> },
5654
}
5755

58-
// TODO(matheus23): Remove this, or remove DnsError::Staggered, but don't keep both.
59-
mod staggered {
60-
use snafu::{Backtrace, GenerateImplicitData, Snafu};
61-
62-
use super::LookupError;
63-
64-
/// Error returned when an input value is too long for [`crate::node_info::UserData`].
65-
#[allow(missing_docs)]
66-
#[derive(Debug, Snafu)]
67-
#[snafu(display("no calls succeeded: [{}]", errors.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("")))]
68-
pub struct Error {
69-
backtrace: Option<Backtrace>,
70-
#[snafu(implicit)]
71-
span_trace: n0_snafu::SpanTrace,
72-
errors: Vec<LookupError>,
73-
}
56+
/// Error returned when an input value is too long for [`crate::node_info::UserData`].
57+
#[allow(missing_docs)]
58+
#[derive(Debug, Snafu)]
59+
#[snafu(module)]
60+
#[snafu(display("no calls succeeded: [{}]", errors.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("")))]
61+
pub struct StaggeredError<E: std::fmt::Debug + std::fmt::Display> {
62+
backtrace: Option<Backtrace>,
63+
#[snafu(implicit)]
64+
span_trace: n0_snafu::SpanTrace,
65+
errors: Vec<E>,
66+
}
7467

75-
impl Error {
76-
pub(crate) fn new(errors: Vec<LookupError>) -> Self {
77-
Self {
78-
errors,
79-
backtrace: GenerateImplicitData::generate(),
80-
span_trace: n0_snafu::SpanTrace::generate(),
81-
}
68+
impl<E: std::fmt::Debug + std::fmt::Display> StaggeredError<E> {
69+
pub(crate) fn new(errors: Vec<E>) -> Self {
70+
Self {
71+
errors,
72+
backtrace: GenerateImplicitData::generate(),
73+
span_trace: n0_snafu::SpanTrace::generate(),
8274
}
8375
}
8476
}
8577

86-
pub use staggered::*;
87-
8878
/// The DNS resolver used throughout `iroh`.
8979
#[derive(Debug, Clone)]
9080
pub struct DnsResolver(TokioResolver);
@@ -252,12 +242,10 @@ impl DnsResolver {
252242
host: impl ToString,
253243
timeout: Duration,
254244
delays_ms: &[u64],
255-
) -> Result<impl Iterator<Item = IpAddr>, DnsError> {
245+
) -> Result<impl Iterator<Item = IpAddr>, StaggeredError<DnsError>> {
256246
let host = host.to_string();
257247
let f = || self.lookup_ipv4(host.clone(), timeout);
258-
stagger_call(f, delays_ms)
259-
.await
260-
.map_err(|errors| StaggeredSnafu { errors }.build())
248+
stagger_call(f, delays_ms).await
261249
}
262250

263251
/// Perform an ipv6 lookup with a timeout in a staggered fashion.
@@ -271,12 +259,10 @@ impl DnsResolver {
271259
host: impl ToString,
272260
timeout: Duration,
273261
delays_ms: &[u64],
274-
) -> Result<impl Iterator<Item = IpAddr>, DnsError> {
262+
) -> Result<impl Iterator<Item = IpAddr>, StaggeredError<DnsError>> {
275263
let host = host.to_string();
276264
let f = || self.lookup_ipv6(host.clone(), timeout);
277-
stagger_call(f, delays_ms)
278-
.await
279-
.map_err(|errors| StaggeredSnafu { errors }.build())
265+
stagger_call(f, delays_ms).await
280266
}
281267

282268
/// Race an ipv4 and ipv6 lookup with a timeout in a staggered fashion.
@@ -291,12 +277,10 @@ impl DnsResolver {
291277
host: impl ToString,
292278
timeout: Duration,
293279
delays_ms: &[u64],
294-
) -> Result<impl Iterator<Item = IpAddr>, DnsError> {
280+
) -> Result<impl Iterator<Item = IpAddr>, StaggeredError<DnsError>> {
295281
let host = host.to_string();
296282
let f = || self.lookup_ipv4_ipv6(host.clone(), timeout);
297-
stagger_call(f, delays_ms)
298-
.await
299-
.map_err(|errors| StaggeredSnafu { errors }.build())
283+
stagger_call(f, delays_ms).await
300284
}
301285

302286
/// Looks up node info by [`NodeId`] and origin domain name.
@@ -335,11 +319,9 @@ impl DnsResolver {
335319
&self,
336320
name: &str,
337321
delays_ms: &[u64],
338-
) -> Result<NodeInfo, staggered::Error> {
322+
) -> Result<NodeInfo, StaggeredError<LookupError>> {
339323
let f = || self.lookup_node_by_domain_name(name);
340-
stagger_call(f, delays_ms)
341-
.await
342-
.map_err(staggered::Error::new)
324+
stagger_call(f, delays_ms).await
343325
}
344326

345327
/// Looks up node info by [`NodeId`] and origin domain name.
@@ -353,11 +335,9 @@ impl DnsResolver {
353335
node_id: &NodeId,
354336
origin: &str,
355337
delays_ms: &[u64],
356-
) -> Result<NodeInfo, staggered::Error> {
338+
) -> Result<NodeInfo, StaggeredError<LookupError>> {
357339
let f = || self.lookup_node_by_id(node_id, origin);
358-
stagger_call(f, delays_ms)
359-
.await
360-
.map_err(staggered::Error::new)
340+
stagger_call(f, delays_ms).await
361341
}
362342
}
363343

@@ -447,10 +427,15 @@ impl<A: Iterator<Item = IpAddr>, B: Iterator<Item = IpAddr>> Iterator for Lookup
447427
///
448428
/// The first call is performed immediately. The first call to succeed generates an Ok result
449429
/// ignoring any previous error. If all calls fail, an error summarizing all errors is returned.
450-
async fn stagger_call<T, E, F: Fn() -> Fut, Fut: Future<Output = Result<T, E>>>(
430+
async fn stagger_call<
431+
T,
432+
E: std::fmt::Debug + std::fmt::Display,
433+
F: Fn() -> Fut,
434+
Fut: Future<Output = Result<T, E>>,
435+
>(
451436
f: F,
452437
delays_ms: &[u64],
453-
) -> Result<T, Vec<E>> {
438+
) -> Result<T, StaggeredError<E>> {
454439
let mut calls = n0_future::FuturesUnorderedBounded::new(delays_ms.len() + 1);
455440
// NOTE: we add the 0 delay here to have a uniform set of futures. This is more performant than
456441
// using alternatives that allow futures of different types.
@@ -472,7 +457,7 @@ async fn stagger_call<T, E, F: Fn() -> Fut, Fut: Future<Output = Result<T, E>>>(
472457
}
473458
}
474459

475-
Err(errors)
460+
Err(StaggeredError::new(errors))
476461
}
477462

478463
#[cfg(test)]

iroh/src/net_report/reportgen.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::{
2828
use http::StatusCode;
2929
use iroh_base::RelayUrl;
3030
#[cfg(not(wasm_browser))]
31-
use iroh_relay::dns::{DnsError, DnsResolver};
31+
use iroh_relay::dns::{DnsError, DnsResolver, StaggeredError};
3232
use iroh_relay::{
3333
defaults::{DEFAULT_RELAY_QUIC_PORT, DEFAULT_STUN_PORT},
3434
http::RELAY_PROBE_PATH,
@@ -1128,7 +1128,7 @@ async fn run_quic_probe(
11281128
#[non_exhaustive]
11291129
enum CaptivePortalError {
11301130
#[snafu(transparent)]
1131-
DnsLookup { source: DnsError },
1131+
DnsLookup { source: StaggeredError<DnsError> },
11321132
#[snafu(display("Creating HTTP client failed"))]
11331133
CreateReqwestClient { source: reqwest::Error },
11341134
#[snafu(display("HTTP request failed"))]
@@ -1260,7 +1260,7 @@ pub enum GetRelayAddrError {
12601260
#[snafu(display("No suitable relay address found"))]
12611261
NoAddrFound,
12621262
#[snafu(display("DNS lookup failed"))]
1263-
DnsLookup { source: DnsError },
1263+
DnsLookup { source: StaggeredError<DnsError> },
12641264
#[snafu(display("Relay node is not suitable for non-STUN probes"))]
12651265
UnsupportedRelayNode,
12661266
#[snafu(display("HTTPS probes are not implemented"))]
@@ -1423,7 +1423,7 @@ enum MeasureHttpsLatencyError {
14231423
InvalidUrl { source: url::ParseError },
14241424
#[cfg(not(wasm_browser))]
14251425
#[snafu(transparent)]
1426-
DnsLookup { source: DnsError },
1426+
DnsLookup { source: StaggeredError<DnsError> },
14271427
#[cfg(not(wasm_browser))]
14281428
#[snafu(display("Invalid certificate"))]
14291429
InvalidCertificate { source: reqwest::Error },

0 commit comments

Comments
 (0)