Skip to content

Commit 11a8d0e

Browse files
committed
Make a separate XXXCases snafu error for each case
1 parent f654f5d commit 11a8d0e

File tree

4 files changed

+110
-52
lines changed

4 files changed

+110
-52
lines changed

src/api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl From<RequestError> for Error {
174174
fn from(e: RequestError) -> Self {
175175
match e {
176176
RequestError::Rpc { source, .. } => Self::Io(source.into()),
177-
RequestError::Inner { source, .. } => source.into(),
177+
RequestError::Inner { source, .. } => source,
178178
}
179179
}
180180
}

src/api/remote.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ impl GetProgress {
9494

9595
pub async fn complete(self) -> GetResult<Stats> {
9696
just_result(self.stream()).await.unwrap_or_else(|| {
97-
Err(LocalFailureSnafu.into_error(anyhow::anyhow!("stream closed without result")))
97+
Err(LocalFailureSnafu
98+
.into_error(anyhow::anyhow!("stream closed without result").into()))
9899
})
99100
}
100101
}
@@ -503,15 +504,15 @@ impl Remote {
503504
let local = self
504505
.local(content)
505506
.await
506-
.map_err(|e| LocalFailureSnafu.into_error(e))?;
507+
.map_err(|e| LocalFailureSnafu.into_error(e.into()))?;
507508
if local.is_complete() {
508509
return Ok(Default::default());
509510
}
510511
let request = local.missing();
511512
let conn = conn
512513
.connection()
513514
.await
514-
.map_err(|e| LocalFailureSnafu.into_error(e))?;
515+
.map_err(|e| LocalFailureSnafu.into_error(e.into()))?;
515516
let stats = self.execute_get_sink(conn, request, progress).await?;
516517
Ok(stats)
517518
}
@@ -682,7 +683,7 @@ impl Remote {
682683
.await
683684
.map_err(|e| LocalFailureSnafu.into_error(e.into()))?,
684685
)
685-
.map_err(|source| BadRequestSnafu.into_error(source))?;
686+
.map_err(|source| BadRequestSnafu.into_error(source.into()))?;
686687
// let mut hash_seq = LazyHashSeq::new(store.blobs().clone(), root);
687688
loop {
688689
let at_start_child = match next_child {
@@ -909,7 +910,8 @@ async fn get_blob_ranges_impl(
909910
};
910911
let complete = async move {
911912
handle.rx.await.map_err(|e| {
912-
LocalFailureSnafu.into_error(anyhow::anyhow!("error reading from import stream: {e}"))
913+
LocalFailureSnafu
914+
.into_error(anyhow::anyhow!("error reading from import stream: {e}").into())
913915
})
914916
};
915917
let (_, end) = tokio::try_join!(complete, write)?;

src/get/error.rs

Lines changed: 100 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,100 @@
11
//! Error returned from get operations
2+
use std::io;
23

34
use iroh::endpoint::{self, ClosedStream};
45
use n0_snafu::SpanTrace;
56
use nested_enum_utils::common_fields;
7+
use quinn::{ConnectionError, ReadError, WriteError};
68
use snafu::{Backtrace, IntoError, Snafu};
79

8-
#[common_fields({
9-
backtrace: Option<Backtrace>,
10-
#[snafu(implicit)]
11-
span_trace: SpanTrace,
12-
})]
10+
use crate::{
11+
api::ExportBaoError,
12+
get::fsm::{AtBlobHeaderNextError, ConnectedNextError, DecodeError},
13+
};
14+
15+
#[derive(Debug, Snafu)]
16+
pub enum NotFoundCases {
17+
#[snafu(transparent)]
18+
AtBlobHeaderNext { source: AtBlobHeaderNextError },
19+
#[snafu(transparent)]
20+
Decode { source: DecodeError },
21+
}
22+
23+
#[derive(Debug, Snafu)]
24+
pub enum NoncompliantNodeCases {
25+
#[snafu(transparent)]
26+
Connection { source: ConnectionError },
27+
#[snafu(transparent)]
28+
Decode { source: DecodeError },
29+
}
30+
31+
#[derive(Debug, Snafu)]
32+
pub enum RemoteResetCases {
33+
#[snafu(transparent)]
34+
Read { source: ReadError },
35+
#[snafu(transparent)]
36+
Write { source: WriteError },
37+
#[snafu(transparent)]
38+
Connection { source: ConnectionError },
39+
}
40+
41+
#[derive(Debug, Snafu)]
42+
pub enum BadRequestCases {
43+
#[snafu(transparent)]
44+
Anyhow { source: anyhow::Error },
45+
#[snafu(transparent)]
46+
Postcard { source: postcard::Error },
47+
#[snafu(transparent)]
48+
ConnectedNext { source: ConnectedNextError },
49+
}
50+
51+
#[derive(Debug, Snafu)]
52+
pub enum LocalFailureCases {
53+
#[snafu(transparent)]
54+
Io {
55+
source: io::Error,
56+
},
57+
#[snafu(transparent)]
58+
Anyhow {
59+
source: anyhow::Error,
60+
},
61+
#[snafu(transparent)]
62+
IrpcSend {
63+
source: irpc::channel::SendError,
64+
},
65+
#[snafu(transparent)]
66+
Irpc {
67+
source: irpc::Error,
68+
},
69+
#[snafu(transparent)]
70+
ExportBao {
71+
source: ExportBaoError,
72+
},
73+
TokioSend {},
74+
}
75+
76+
impl<T> From<tokio::sync::mpsc::error::SendError<T>> for LocalFailureCases {
77+
fn from(_: tokio::sync::mpsc::error::SendError<T>) -> Self {
78+
LocalFailureCases::TokioSend {}
79+
}
80+
}
81+
1382
#[derive(Debug, Snafu)]
14-
pub enum GetNotFoundError {
15-
AtBlobHeader {},
83+
pub enum IoCases {
84+
#[snafu(transparent)]
85+
Io { source: io::Error },
86+
#[snafu(transparent)]
87+
ConnectionError { source: endpoint::ConnectionError },
88+
#[snafu(transparent)]
89+
ReadError { source: endpoint::ReadError },
90+
#[snafu(transparent)]
91+
WriteError { source: endpoint::WriteError },
92+
#[snafu(transparent)]
93+
ClosedStream { source: endpoint::ClosedStream },
94+
#[snafu(transparent)]
95+
ConnectedNextError { source: ConnectedNextError },
96+
#[snafu(transparent)]
97+
AtBlobHeaderNextError { source: AtBlobHeaderNextError },
1698
}
1799

18100
/// Failures for a get operation
@@ -26,24 +108,24 @@ pub enum GetNotFoundError {
26108
pub enum GetError {
27109
/// Hash not found, or a requested chunk for the hash not found.
28110
#[snafu(display("Data for hash not found"))]
29-
NotFound { source: GetNotFoundError },
111+
NotFound { source: NotFoundCases },
30112
/// Remote has reset the connection.
31113
#[snafu(display("Remote has reset the connection"))]
32-
RemoteReset { source: anyhow::Error },
114+
RemoteReset { source: RemoteResetCases },
33115
/// Remote behaved in a non-compliant way.
34116
#[snafu(display("Remote behaved in a non-compliant way"))]
35-
NoncompliantNode { source: anyhow::Error },
117+
NoncompliantNode { source: NoncompliantNodeCases },
36118

37119
/// Network or IO operation failed.
38120
#[snafu(display("A network or IO operation failed"))]
39-
Io { source: anyhow::Error },
121+
Io { source: IoCases },
40122

41123
/// Our download request is invalid.
42124
#[snafu(display("Our download request is invalid"))]
43-
BadRequest { source: anyhow::Error },
125+
BadRequest { source: BadRequestCases },
44126
/// Operation failed on the local node.
45127
#[snafu(display("Operation failed on the local node"))]
46-
LocalFailure { source: anyhow::Error },
128+
LocalFailure { source: LocalFailureCases },
47129
}
48130

49131
pub type GetResult<T> = std::result::Result<T, GetError>;
@@ -168,16 +250,10 @@ impl From<crate::get::fsm::AtBlobHeaderNextError> for GetError {
168250
fn from(value: crate::get::fsm::AtBlobHeaderNextError) -> Self {
169251
use crate::get::fsm::AtBlobHeaderNextError::*;
170252
match value {
171-
NotFound {
172-
backtrace,
173-
span_trace,
174-
} => {
253+
e @ NotFound { .. } => {
175254
// > This indicates that the provider does not have the requested data.
176255
// peer might have the data later, simply retry it
177-
NotFoundSnafu.into_error(GetNotFoundError::AtBlobHeader {
178-
backtrace,
179-
span_trace,
180-
})
256+
NotFoundSnafu.into_error(e.into())
181257
}
182258
EndpointRead { source, .. } => source.into(),
183259
e @ Io { .. } => {
@@ -193,29 +269,9 @@ impl From<crate::get::fsm::DecodeError> for GetError {
193269
use crate::get::fsm::DecodeError::*;
194270

195271
match value {
196-
ChunkNotFound {
197-
backtrace,
198-
span_trace,
199-
} => NotFoundSnafu.into_error(GetNotFoundError::AtBlobHeader {
200-
backtrace,
201-
span_trace,
202-
}),
203-
ParentNotFound {
204-
backtrace,
205-
span_trace,
206-
..
207-
} => NotFoundSnafu.into_error(GetNotFoundError::AtBlobHeader {
208-
backtrace,
209-
span_trace,
210-
}),
211-
LeafNotFound {
212-
backtrace,
213-
span_trace,
214-
..
215-
} => NotFoundSnafu.into_error(GetNotFoundError::AtBlobHeader {
216-
backtrace,
217-
span_trace,
218-
}),
272+
e @ ChunkNotFound { .. } => NotFoundSnafu.into_error(e.into()),
273+
e @ ParentNotFound { .. } => NotFoundSnafu.into_error(e.into()),
274+
e @ LeafNotFound { .. } => NotFoundSnafu.into_error(e.into()),
219275
e @ ParentHashMismatch { .. } => {
220276
// TODO(@divma): did the peer sent wrong data? is it corrupted? did we sent a wrong
221277
// request?

src/get/request.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl GetBlobResult {
5858
let mut parts = Vec::new();
5959
let stats = loop {
6060
let Some(item) = self.next().await else {
61-
return Err(LocalFailureSnafu.into_error(anyhow::anyhow!("unexpected end")));
61+
return Err(LocalFailureSnafu.into_error(anyhow::anyhow!("unexpected end").into()));
6262
};
6363
match item {
6464
GetBlobItem::Item(item) => {
@@ -238,7 +238,7 @@ pub async fn get_hash_seq_and_sizes(
238238
let (at_blob_content, size) = at_start_root.next().await?;
239239
// check the size to avoid parsing a maliciously large hash seq
240240
if size > max_size {
241-
return Err(BadRequestSnafu.into_error(anyhow::anyhow!("size too large")));
241+
return Err(BadRequestSnafu.into_error(anyhow::anyhow!("size too large").into()));
242242
}
243243
let (mut curr, hash_seq) = at_blob_content.concatenate_into_vec().await?;
244244
let hash_seq = HashSeq::try_from(Bytes::from(hash_seq))

0 commit comments

Comments
 (0)