Skip to content

Commit ae967e3

Browse files
authored
Merge pull request #2 from n0-computer/snafu-errors-2nd-attempt
refactor: convert thiserror to snafu and remove anyhow in public apis
2 parents 969950c + 744d85b commit ae967e3

File tree

18 files changed

+1251
-1181
lines changed

18 files changed

+1251
-1181
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ bao-tree = { version = "0.15.1", features = ["experimental-mixed", "tokio_fsm",
99
bytes = { version = "1", features = ["serde"] }
1010
derive_more = { version = "2.0.1", features = ["from", "try_from", "into", "debug", "display", "deref", "deref_mut"] }
1111
futures-lite = "2.6.0"
12-
quinn = { package = "iroh-quinn", version = "0.13.0" }
12+
quinn = { package = "iroh-quinn", version = "0.14.0" }
1313
n0-future = "0.1.2"
14+
n0-snafu = "0.2.0"
1415
range-collections = { version = "0.4.6", features = ["serde"] }
1516
redb = "2.4.0"
1617
smallvec = { version = "1", features = ["serde", "const_new"] }
17-
thiserror = "2.0.11"
18+
snafu = "0.8.5"
1819
tokio = { version = "1.43.0", features = ["full"] }
1920
tokio-util = { version = "0.7.13", features = ["full"] }
2021
tracing = "0.1.41"
@@ -25,13 +26,13 @@ serde = "1.0.217"
2526
postcard = { version = "1.1.1", features = ["experimental-derive", "use-std"] }
2627
data-encoding = "2.8.0"
2728
chrono = "0.4.39"
28-
nested_enum_utils = "0.1.0"
29+
nested_enum_utils = "0.2.1"
2930
ref-cast = "1.0.24"
3031
arrayvec = "0.7.6"
31-
iroh = "0.35.0"
32+
iroh = "0.35"
3233
self_cell = "1.1.0"
3334
genawaiter = { version = "0.99.1", features = ["futures03"] }
34-
iroh-base = "0.35.0"
35+
iroh-base = "0.35"
3536
reflink-copy = "0.1.24"
3637
irpc = { version = "0.4.0", features = ["rpc", "quinn_endpoint_setup", "message_spans", "stream", "derive"], default-features = false }
3738
iroh-metrics = { version = "0.32.0" }
@@ -56,3 +57,9 @@ walkdir = "2.5.0"
5657
hide-proto-docs = []
5758
metrics = []
5859
default = ["hide-proto-docs"]
60+
61+
[patch.crates-io]
62+
iroh = { git = "https://github.com/n0-computer/iroh.git", branch = "ramfox/ticket-error" }
63+
iroh-base = { git = "https://github.com/n0-computer/iroh.git", branch = "ramfox/ticket-error" }
64+
irpc = { git = "https://github.com/n0-computer/irpc.git", branch = "iroh-quinn-latest" }
65+
irpc-derive = { git = "https://github.com/n0-computer/irpc.git", branch = "iroh-quinn-latest" }

examples/random_store.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{env, path::PathBuf, str::FromStr};
22

33
use anyhow::{Context, Result};
44
use clap::{Parser, Subcommand};
5-
use iroh::SecretKey;
5+
use iroh::{SecretKey, Watcher};
66
use iroh_base::ticket::NodeTicket;
77
use iroh_blobs::{
88
HashAndFormat,
@@ -240,7 +240,7 @@ async fn provide(args: ProvideArgs) -> anyhow::Result<()> {
240240
let router = iroh::protocol::Router::builder(endpoint.clone())
241241
.accept(iroh_blobs::ALPN, blobs)
242242
.spawn();
243-
let addr = router.endpoint().node_addr().await?;
243+
let addr = router.endpoint().node_addr().initialized().await?;
244244
let ticket = NodeTicket::from(addr.clone());
245245
println!("Node address: {:?}", addr);
246246
println!("ticket:\n{}", ticket);

src/api.rs

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ use std::{io, net::SocketAddr, ops::Deref, sync::Arc};
66

77
use iroh::Endpoint;
88
use irpc::rpc::{Handler, listen};
9+
use n0_snafu::SpanTrace;
10+
use nested_enum_utils::common_fields;
911
use proto::{Request, ShutdownRequest, SyncDbRequest};
1012
use ref_cast::RefCast;
1113
use serde::{Deserialize, Serialize};
14+
use snafu::{Backtrace, IntoError, Snafu};
1215
use tags::Tags;
1316

1417
pub mod blobs;
@@ -20,85 +23,123 @@ pub use crate::{store::util::Tag, util::temp_tag::TempTag};
2023

2124
pub(crate) type ApiClient = irpc::Client<proto::Command, proto::Request, proto::StoreService>;
2225

23-
#[derive(Debug, thiserror::Error)]
26+
#[common_fields({
27+
backtrace: Option<Backtrace>,
28+
#[snafu(implicit)]
29+
span_trace: SpanTrace,
30+
})]
31+
#[allow(missing_docs)]
32+
#[non_exhaustive]
33+
#[derive(Debug, Snafu)]
2434
pub enum RequestError {
2535
/// Request failed due to rpc error.
26-
#[error("rpc error: {0}")]
27-
Rpc(#[from] irpc::Error),
36+
#[snafu(display("rpc error: {source}"))]
37+
Rpc { source: irpc::Error },
2838
/// Request failed due an actual error.
29-
#[error("inner error: {0}")]
30-
Inner(#[from] Error),
39+
#[snafu(display("inner error: {source}"))]
40+
Inner { source: Error },
3141
}
3242

33-
pub type RequestResult<T> = std::result::Result<T, RequestError>;
34-
35-
impl From<irpc::channel::SendError> for RequestError {
36-
fn from(e: irpc::channel::SendError) -> Self {
37-
Self::Rpc(e.into())
43+
impl From<irpc::Error> for RequestError {
44+
fn from(value: irpc::Error) -> Self {
45+
RpcSnafu.into_error(value)
3846
}
3947
}
4048

41-
impl From<irpc::channel::RecvError> for RequestError {
42-
fn from(e: irpc::channel::RecvError) -> Self {
43-
Self::Rpc(e.into())
49+
impl From<Error> for RequestError {
50+
fn from(value: Error) -> Self {
51+
InnerSnafu.into_error(value)
4452
}
4553
}
4654

47-
impl From<irpc::RequestError> for RequestError {
48-
fn from(e: irpc::RequestError) -> Self {
49-
Self::Rpc(e.into())
55+
impl From<io::Error> for RequestError {
56+
fn from(value: io::Error) -> Self {
57+
InnerSnafu.into_error(value.into())
5058
}
5159
}
5260

53-
impl From<irpc::rpc::WriteError> for RequestError {
54-
fn from(e: irpc::rpc::WriteError) -> Self {
55-
Self::Rpc(e.into())
61+
impl From<irpc::channel::RecvError> for RequestError {
62+
fn from(value: irpc::channel::RecvError) -> Self {
63+
RpcSnafu.into_error(value.into())
5664
}
5765
}
5866

59-
impl From<io::Error> for RequestError {
60-
fn from(e: io::Error) -> Self {
61-
Self::Inner(e.into())
62-
}
63-
}
67+
pub type RequestResult<T> = std::result::Result<T, RequestError>;
6468

65-
#[derive(Debug, thiserror::Error)]
69+
#[common_fields({
70+
backtrace: Option<Backtrace>,
71+
#[snafu(implicit)]
72+
span_trace: SpanTrace,
73+
})]
74+
#[allow(missing_docs)]
75+
#[non_exhaustive]
76+
#[derive(Debug, Snafu)]
6677
pub enum ExportBaoError {
67-
#[error("send error: {0}")]
68-
Send(#[from] irpc::channel::SendError),
69-
#[error("recv error: {0}")]
70-
Recv(#[from] irpc::channel::RecvError),
71-
#[error("request error: {0}")]
72-
Request(#[from] irpc::RequestError),
73-
#[error("io error: {0}")]
74-
Io(#[from] io::Error),
75-
#[error("encode error: {0}")]
76-
Inner(#[from] bao_tree::io::EncodeError),
78+
#[snafu(display("send error: {source}"))]
79+
Send { source: irpc::channel::SendError },
80+
#[snafu(display("recv error: {source}"))]
81+
Recv { source: irpc::channel::RecvError },
82+
#[snafu(display("request error: {source}"))]
83+
Request { source: irpc::RequestError },
84+
#[snafu(display("io error: {source}"))]
85+
ExportBaoIo { source: io::Error },
86+
#[snafu(display("encode error: {source}"))]
87+
ExportBaoInner { source: bao_tree::io::EncodeError },
7788
}
7889

7990
impl From<ExportBaoError> for Error {
8091
fn from(e: ExportBaoError) -> Self {
8192
match e {
82-
ExportBaoError::Send(e) => Self::Io(e.into()),
83-
ExportBaoError::Recv(e) => Self::Io(e.into()),
84-
ExportBaoError::Request(e) => Self::Io(e.into()),
85-
ExportBaoError::Io(e) => Self::Io(e),
86-
ExportBaoError::Inner(e) => Self::Io(e.into()),
93+
ExportBaoError::Send { source, .. } => Self::Io(source.into()),
94+
ExportBaoError::Recv { source, .. } => Self::Io(source.into()),
95+
ExportBaoError::Request { source, .. } => Self::Io(source.into()),
96+
ExportBaoError::ExportBaoIo { source, .. } => Self::Io(source),
97+
ExportBaoError::ExportBaoInner { source, .. } => Self::Io(source.into()),
8798
}
8899
}
89100
}
90101

91102
impl From<irpc::Error> for ExportBaoError {
92103
fn from(e: irpc::Error) -> Self {
93104
match e {
94-
irpc::Error::Recv(e) => Self::Recv(e),
95-
irpc::Error::Send(e) => Self::Send(e),
96-
irpc::Error::Request(e) => Self::Request(e),
97-
irpc::Error::Write(e) => Self::Io(e.into()),
105+
irpc::Error::Recv(e) => RecvSnafu.into_error(e),
106+
irpc::Error::Send(e) => SendSnafu.into_error(e),
107+
irpc::Error::Request(e) => RequestSnafu.into_error(e),
108+
irpc::Error::Write(e) => ExportBaoIoSnafu.into_error(e.into()),
98109
}
99110
}
100111
}
101112

113+
impl From<io::Error> for ExportBaoError {
114+
fn from(value: io::Error) -> Self {
115+
ExportBaoIoSnafu.into_error(value)
116+
}
117+
}
118+
119+
impl From<irpc::channel::RecvError> for ExportBaoError {
120+
fn from(value: irpc::channel::RecvError) -> Self {
121+
RecvSnafu.into_error(value)
122+
}
123+
}
124+
125+
impl From<irpc::channel::SendError> for ExportBaoError {
126+
fn from(value: irpc::channel::SendError) -> Self {
127+
SendSnafu.into_error(value)
128+
}
129+
}
130+
131+
impl From<irpc::RequestError> for ExportBaoError {
132+
fn from(value: irpc::RequestError) -> Self {
133+
RequestSnafu.into_error(value)
134+
}
135+
}
136+
137+
impl From<bao_tree::io::EncodeError> for ExportBaoError {
138+
fn from(value: bao_tree::io::EncodeError) -> Self {
139+
ExportBaoInnerSnafu.into_error(value)
140+
}
141+
}
142+
102143
pub type ExportBaoResult<T> = std::result::Result<T, ExportBaoError>;
103144

104145
#[derive(Debug, derive_more::Display, derive_more::From, Serialize, Deserialize)]
@@ -132,8 +173,8 @@ impl From<irpc::Error> for Error {
132173
impl From<RequestError> for Error {
133174
fn from(e: RequestError) -> Self {
134175
match e {
135-
RequestError::Rpc(e) => Self::Io(e.into()),
136-
RequestError::Inner(e) => e,
176+
RequestError::Rpc { source, .. } => Self::Io(source.into()),
177+
RequestError::Inner { source, .. } => source,
137178
}
138179
}
139180
}

src/api/blobs.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ impl Blobs {
430430
&self,
431431
hash: Hash,
432432
ranges: ChunkRanges,
433-
stream: &mut quinn::RecvStream,
433+
stream: &mut iroh::endpoint::RecvStream,
434434
) -> RequestResult<()> {
435435
let reader = TokioStreamReader::new(stream);
436436
self.import_bao_reader(hash, ranges, reader).await?;
@@ -1024,16 +1024,13 @@ impl ExportBaoProgress {
10241024
let mut data = vec![0u8; 64];
10251025
data[..32].copy_from_slice(parent.pair.0.as_bytes());
10261026
data[32..].copy_from_slice(parent.pair.1.as_bytes());
1027-
target
1028-
.write_all(&data)
1029-
.await
1030-
.map_err(|e| super::ExportBaoError::Io(e.into()))?;
1027+
target.write_all(&data).await.map_err(io::Error::from)?;
10311028
}
10321029
EncodedItem::Leaf(leaf) => {
10331030
target
10341031
.write_chunk(leaf.data)
10351032
.await
1036-
.map_err(|e| super::ExportBaoError::Io(e.into()))?;
1033+
.map_err(io::Error::from)?;
10371034
}
10381035
EncodedItem::Done => break,
10391036
EncodedItem::Error(cause) => return Err(cause.into()),
@@ -1062,18 +1059,15 @@ impl ExportBaoProgress {
10621059
let mut data = vec![0u8; 64];
10631060
data[..32].copy_from_slice(parent.pair.0.as_bytes());
10641061
data[32..].copy_from_slice(parent.pair.1.as_bytes());
1065-
writer
1066-
.write_all(&data)
1067-
.await
1068-
.map_err(|e| super::ExportBaoError::Io(e.into()))?;
1062+
writer.write_all(&data).await.map_err(io::Error::from)?;
10691063
progress.log_other_write(64);
10701064
}
10711065
EncodedItem::Leaf(leaf) => {
10721066
let len = leaf.data.len();
10731067
writer
10741068
.write_chunk(leaf.data)
10751069
.await
1076-
.map_err(|e| super::ExportBaoError::Io(e.into()))?;
1070+
.map_err(io::Error::from)?;
10771071
progress.notify_payload_write(index, leaf.offset, len).await;
10781072
}
10791073
EncodedItem::Done => break,

src/api/downloader.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ impl DialNode {
626626
Ok(Err(e)) => {
627627
warn!("Failed to connect to node {}: {}", self.id, e);
628628
*guard = SlotState::AttemptFailed(SystemTime::now());
629-
Err(e)
629+
Err(e.into())
630630
}
631631
Err(e) => {
632632
warn!("Failed to connect to node {}: {}", self.id, e);
@@ -685,6 +685,7 @@ mod tests {
685685
use std::ops::Deref;
686686

687687
use bao_tree::ChunkRanges;
688+
use iroh::Watcher;
688689
use n0_future::StreamExt;
689690
use testresult::TestResult;
690691

@@ -706,9 +707,9 @@ mod tests {
706707
let (r3, store3, _) = node_test_setup_fs(testdir.path().join("c")).await?;
707708
let tt1 = store1.add_slice("hello world").await?;
708709
let tt2 = store2.add_slice("hello world 2").await?;
709-
let node1_addr = r1.endpoint().node_addr().await?;
710+
let node1_addr = r1.endpoint().node_addr().initialized().await?;
710711
let node1_id = node1_addr.node_id;
711-
let node2_addr = r2.endpoint().node_addr().await?;
712+
let node2_addr = r2.endpoint().node_addr().initialized().await?;
712713
let node2_id = node2_addr.node_id;
713714
let swarm = Downloader::new(&store3, r3.endpoint());
714715
r3.endpoint().add_node_addr(node1_addr.clone())?;
@@ -745,9 +746,9 @@ mod tests {
745746
format: crate::BlobFormat::HashSeq,
746747
})
747748
.await?;
748-
let node1_addr = r1.endpoint().node_addr().await?;
749+
let node1_addr = r1.endpoint().node_addr().initialized().await?;
749750
let node1_id = node1_addr.node_id;
750-
let node2_addr = r2.endpoint().node_addr().await?;
751+
let node2_addr = r2.endpoint().node_addr().initialized().await?;
751752
let node2_id = node2_addr.node_id;
752753
let swarm = Downloader::new(&store3, r3.endpoint());
753754
r3.endpoint().add_node_addr(node1_addr.clone())?;
@@ -814,9 +815,9 @@ mod tests {
814815
format: crate::BlobFormat::HashSeq,
815816
})
816817
.await?;
817-
let node1_addr = r1.endpoint().node_addr().await?;
818+
let node1_addr = r1.endpoint().node_addr().initialized().await?;
818819
let node1_id = node1_addr.node_id;
819-
let node2_addr = r2.endpoint().node_addr().await?;
820+
let node2_addr = r2.endpoint().node_addr().initialized().await?;
820821
let node2_id = node2_addr.node_id;
821822
let swarm = Downloader::new(&store3, r3.endpoint());
822823
r3.endpoint().add_node_addr(node1_addr.clone())?;

0 commit comments

Comments
 (0)