Skip to content

Commit 7b9c95b

Browse files
refactor!: convert from snafu to n0-error (#3561)
## Description Changes the error handling across all crates in this repo from `snafu`/`n0-snafu` to **`n0-error`**. The latter is our new error library which features call-site location tracking and better ergonomics than snafu. Repo: https://github.com/n0-computer/n0-error Docs: https://docs.rs/n0-error/ *Note:* The initial version of this PR was written by an AI (OpenAI codex) which I instructed in numerous prompts to convert iroh from n0-snafu/snafu to n0-error. It has since been cleaned up and reviewed line-by-line. ## Breaking Changes *Changed* * All error structs and enum variants now have a field `meta: n0_error::Meta`. Fields `backtrace` and `span_trace` are removed. * All error structs and enums no longer implement `snafu::ErrorCompat`. They now implement `n0_error::StackError`. All our errors keep implementing `std::error::Error`. For downstream uses of these errors, not much changed. * If you previously used `n0-snafu` to work with iroh errors, we recommend you switch to `n0-error`. See the [docs]( https://docs.rs/n0-error/) for how to work with n0-error. ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist <!-- Remove any that are not relevant. --> - [x] Self-review. - [x] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [x] Tests if relevant. - [x] All breaking changes documented. - [ ] List all breaking changes in the above "Breaking Changes" section. - [ ] Open an issue or PR on any number0 repos that are affected by this breaking change. Give guidance on how the updates should be handled or do the actual updates themselves. The major ones are: - [ ] [`quic-rpc`](https://github.com/n0-computer/quic-rpc) - [ ] [`iroh-gossip`](https://github.com/n0-computer/iroh-gossip) - [ ] [`iroh-blobs`](https://github.com/n0-computer/iroh-blobs) - [ ] [`dumbpipe`](https://github.com/n0-computer/dumbpipe) - [ ] [`sendme`](https://github.com/n0-computer/sendme) --------- Co-authored-by: dignifiedquire <[email protected]>
1 parent c2bdbe2 commit 7b9c95b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1819
-1982
lines changed

Cargo.lock

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

iroh-base/Cargo.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ derive_more = { version = "2.0.1", features = ["display"], optional = true }
2222
url = { version = "2.5.3", features = ["serde"], optional = true }
2323
rand_core = { version = "0.9.3", optional = true }
2424
serde = { version = "1", features = ["derive", "rc"] }
25-
snafu = { version = "0.8.5", features = ["rust_1_81"], optional = true }
26-
n0-snafu = "0.2.2"
27-
nested_enum_utils = "0.2.0"
25+
n0-error = "0.1.0"
2826
zeroize = { version = "1.8.2", optional = true, features = ["derive"] }
2927
zeroize_derive = { version = "1.4.2", optional = true } # needed for minimal versions
3028

@@ -44,7 +42,6 @@ key = [
4442
"dep:ed25519-dalek",
4543
"dep:url",
4644
"dep:derive_more",
47-
"dep:snafu",
4845
"dep:data-encoding",
4946
"dep:rand_core",
5047
"dep:zeroize",
@@ -54,7 +51,6 @@ key = [
5451
relay = [
5552
"dep:url",
5653
"dep:derive_more",
57-
"dep:snafu",
5854
]
5955

6056
[package.metadata.docs.rs]

iroh-base/src/key.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ use std::{
1111

1212
use curve25519_dalek::edwards::CompressedEdwardsY;
1313
use ed25519_dalek::{SigningKey, VerifyingKey};
14-
use nested_enum_utils::common_fields;
14+
use n0_error::{ensure, stack_error};
1515
use rand_core::CryptoRng;
1616
use serde::{Deserialize, Serialize, de, ser};
17-
use snafu::{Backtrace, Snafu};
1817

1918
/// A public key.
2019
///
@@ -128,7 +127,7 @@ impl PublicKey {
128127
pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), SignatureError> {
129128
self.as_verifying_key()
130129
.verify_strict(message, &signature.0)
131-
.map_err(|_| SignatureSnafu.build())
130+
.map_err(|_| SignatureError::new())
132131
}
133132

134133
/// Convert to a hex string limited to the first 5 bytes for a friendly string
@@ -204,26 +203,18 @@ impl Display for PublicKey {
204203
}
205204

206205
/// Error when deserialising a [`PublicKey`] or a [`SecretKey`].
207-
#[common_fields({
208-
backtrace: Option<Backtrace>,
209-
#[snafu(implicit)]
210-
span_trace: n0_snafu::SpanTrace,
211-
})]
212-
#[derive(Snafu, Debug)]
206+
#[stack_error(derive, add_meta, from_sources, std_sources)]
213207
#[allow(missing_docs)]
214-
#[snafu(visibility(pub(crate)))]
215208
pub enum KeyParsingError {
216209
/// Error when decoding.
217-
#[snafu(transparent)]
218-
Decode { source: data_encoding::DecodeError },
210+
#[error(transparent)]
211+
Decode(data_encoding::DecodeError),
219212
/// Error when decoding the public key.
220-
#[snafu(transparent)]
221-
Key {
222-
source: ed25519_dalek::SignatureError,
223-
},
213+
#[error(transparent)]
214+
Key(ed25519_dalek::SignatureError),
224215
/// The encoded information had the wrong length.
225-
#[snafu(display("invalid length"))]
226-
DecodeInvalidLength {},
216+
#[error("invalid length")]
217+
DecodeInvalidLength,
227218
}
228219

229220
/// Deserialises the [`PublicKey`] from it's base32 encoding.
@@ -420,9 +411,9 @@ impl Signature {
420411
}
421412

422413
/// Verification of a signature failed.
423-
#[derive(Debug, Snafu)]
424-
#[snafu(display("Invalid signature"))]
425-
pub struct SignatureError;
414+
#[stack_error(derive, add_meta)]
415+
#[error("Invalid signature")]
416+
pub struct SignatureError {}
426417

427418
fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {
428419
let mut bytes = [0u8; 32];
@@ -433,16 +424,18 @@ fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {
433424
} else {
434425
let input = s.to_ascii_uppercase();
435426
let input = input.as_bytes();
436-
if data_encoding::BASE32_NOPAD.decode_len(input.len())? != bytes.len() {
437-
return Err(DecodeInvalidLengthSnafu.build());
438-
}
427+
ensure!(
428+
data_encoding::BASE32_NOPAD.decode_len(input.len())? == bytes.len(),
429+
KeyParsingError::DecodeInvalidLength
430+
);
439431
data_encoding::BASE32_NOPAD.decode_mut(input, &mut bytes)
440432
};
441433
match res {
442434
Ok(len) => {
443-
if len != PublicKey::LENGTH {
444-
return Err(DecodeInvalidLengthSnafu.build());
445-
}
435+
ensure!(
436+
len == PublicKey::LENGTH,
437+
KeyParsingError::DecodeInvalidLength
438+
);
446439
}
447440
Err(partial) => return Err(partial.error.into()),
448441
}

iroh-base/src/relay_url.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{fmt, ops::Deref, str::FromStr, sync::Arc};
22

3+
use n0_error::stack_error;
34
use serde::{Deserialize, Serialize};
4-
use snafu::{Backtrace, ResultExt, Snafu};
55
use url::Url;
66

77
/// A URL identifying a relay server.
@@ -39,12 +39,9 @@ impl From<Url> for RelayUrl {
3939
}
4040

4141
/// Can occur when parsing a string into a [`RelayUrl`].
42-
#[derive(Debug, Snafu)]
43-
#[snafu(display("Failed to parse"))]
44-
pub struct RelayUrlParseError {
45-
source: url::ParseError,
46-
backtrace: Option<Backtrace>,
47-
}
42+
#[stack_error(derive, add_meta)]
43+
#[error("Failed to parse relay URL")]
44+
pub struct RelayUrlParseError(#[error(std_err)] url::ParseError);
4845

4946
/// Support for parsing strings directly.
5047
///
@@ -54,7 +51,7 @@ impl FromStr for RelayUrl {
5451
type Err = RelayUrlParseError;
5552

5653
fn from_str(s: &str) -> Result<Self, Self::Err> {
57-
let inner = Url::from_str(s).context(RelayUrlParseSnafu)?;
54+
let inner = Url::from_str(s).map_err(RelayUrlParseError::new)?;
5855
Ok(RelayUrl::from(inner))
5956
}
6057
}

iroh-dns-server/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ hickory-server = { version = "0.25.1", features = ["https-ring"] }
2828
http = "1.0.0"
2929
humantime = "2.2.0"
3030
humantime-serde = "1.1.1"
31-
iroh-metrics = { version = "0.36", features = ["service"] }
31+
iroh-metrics = { version = "0.37", features = ["service"] }
3232
lru = "0.16"
3333
n0-future = "0.3.0"
34-
n0-snafu = "0.2.2"
3534
pkarr = { version = "5", features = ["relays", "dht"], default-features = false }
3635
rcgen = "0.14"
3736
redb = "3.1.0"
@@ -40,7 +39,7 @@ rustls = { version = "0.23.33", default-features = false, features = ["ring"] }
4039
rustls-pemfile = { version = "2.1" }
4140
serde = { version = "1", features = ["derive"] }
4241
struct_iterable = "0.1.1"
43-
snafu = { version = "0.8.5", features = ["rust_1_81"] }
42+
n0-error = "0.1.0"
4443
strum = { version = "0.27", features = ["derive"] }
4544
tokio = { version = "1", features = ["full"] }
4645
tokio-rustls = { version = "0.26", default-features = false, features = [

iroh-dns-server/benches/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
44
use iroh::{SecretKey, discovery::pkarr::PkarrRelayClient, endpoint_info::EndpointInfo};
55
use iroh_dns_server::{ZoneStore, config::Config, metrics::Metrics, server::Server};
6-
use n0_snafu::Result;
6+
use n0_error::Result;
77
use rand_chacha::rand_core::SeedableRng;
88
use tokio::runtime::Runtime;
99

iroh-dns-server/examples/convert.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::str::FromStr;
22

33
use clap::Parser;
44
use iroh::EndpointId;
5-
use n0_snafu::{Result, ResultExt};
5+
use n0_error::{Result, StdResultExt};
66

77
#[derive(Debug, Parser)]
88
struct Cli {
@@ -21,12 +21,12 @@ fn main() -> Result<()> {
2121
match args.command {
2222
Command::EndpointToPkarr { endpoint_id } => {
2323
let endpoint_id = EndpointId::from_str(&endpoint_id)?;
24-
let public_key = pkarr::PublicKey::try_from(endpoint_id.as_bytes()).e()?;
24+
let public_key = pkarr::PublicKey::try_from(endpoint_id.as_bytes()).anyerr()?;
2525
println!("{}", public_key.to_z32())
2626
}
2727
Command::PkarrToEndpoint { z32_pubkey } => {
28-
let public_key = pkarr::PublicKey::try_from(z32_pubkey.as_str()).e()?;
29-
let endpoint_id = EndpointId::from_bytes(public_key.as_bytes()).e()?;
28+
let public_key = pkarr::PublicKey::try_from(z32_pubkey.as_str()).anyerr()?;
29+
let endpoint_id = EndpointId::from_bytes(public_key.as_bytes())?;
3030
println!("{endpoint_id}")
3131
}
3232
}

iroh-dns-server/examples/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use iroh::{
1010
},
1111
endpoint_info::{EndpointIdExt, EndpointInfo, IROH_TXT_NAME},
1212
};
13-
use n0_snafu::{Result, ResultExt};
13+
use n0_error::{Result, StackResultExt};
1414
use url::Url;
1515

1616
const DEV_PKARR_RELAY_URL: &str = "http://localhost:8080/pkarr";

iroh-dns-server/examples/resolve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use iroh::{
44
discovery::dns::{N0_DNS_ENDPOINT_ORIGIN_PROD, N0_DNS_ENDPOINT_ORIGIN_STAGING},
55
dns::DnsResolver,
66
};
7-
use n0_snafu::{Result, ResultExt};
7+
use n0_error::{Result, StackResultExt, StdResultExt};
88

99
const DEV_DNS_SERVER: &str = "127.0.0.1:5300";
1010
const DEV_DNS_ORIGIN_DOMAIN: &str = "irohdns.example";
@@ -49,7 +49,7 @@ async fn main() -> Result<()> {
4949
let resolver = if let Some(host) = args.dns_server {
5050
let addr = tokio::net::lookup_host(host)
5151
.await
52-
.e()?
52+
.anyerr()?
5353
.next()
5454
.context("failed to resolve DNS server address")?;
5555
DnsResolver::with_nameserver(addr)

iroh-dns-server/src/config.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
time::Duration,
88
};
99

10-
use n0_snafu::{Result, ResultExt};
10+
use n0_error::{Result, StdResultExt};
1111
use serde::{Deserialize, Serialize};
1212
use tracing::info;
1313

@@ -162,8 +162,8 @@ impl Config {
162162
);
163163
let s = tokio::fs::read_to_string(path.as_ref())
164164
.await
165-
.with_context(|| format!("failed to read {}", path.as_ref().to_string_lossy()))?;
166-
let config: Config = toml::from_str(&s).e()?;
165+
.with_std_context(|_| format!("failed to read {}", path.as_ref().to_string_lossy()))?;
166+
let config: Config = toml::from_str(&s).anyerr()?;
167167
Ok(config)
168168
}
169169

@@ -173,7 +173,7 @@ impl Config {
173173
PathBuf::from(val)
174174
} else {
175175
let path = dirs_next::data_dir()
176-
.context("operating environment provides no directory for application data")?;
176+
.std_context("operating environment provides no directory for application data")?;
177177

178178
path.join("iroh-dns")
179179
};

0 commit comments

Comments
 (0)