1
1
//! Error returned from get operations
2
2
3
3
use iroh:: endpoint:: { self , ClosedStream } ;
4
+ use n0_snafu:: SpanTrace ;
5
+ use nested_enum_utils:: common_fields;
6
+ use snafu:: { Backtrace , Snafu } ;
7
+
8
+ #[ common_fields( {
9
+ backtrace: Option <Backtrace >,
10
+ #[ snafu( implicit) ]
11
+ span_trace: SpanTrace ,
12
+ } ) ]
13
+ #[ derive( Debug , Snafu ) ]
14
+ pub enum GetNotFoundError {
15
+ AtBlobHeader { } ,
16
+ }
4
17
5
18
/// Failures for a get operation
6
- #[ derive( Debug , thiserror :: Error ) ]
19
+ #[ derive( Debug , Snafu ) ]
7
20
pub enum GetError {
8
21
/// Hash not found, or a requested chunk for the hash not found.
9
- #[ error ( "Data for hash not found" ) ]
10
- NotFound ( # [ source ] anyhow :: Error ) ,
22
+ #[ snafu ( display ( "Data for hash not found" ) ) ]
23
+ NotFound { source : GetNotFoundError } ,
11
24
/// Remote has reset the connection.
12
- #[ error ( "Remote has reset the connection" ) ]
13
- RemoteReset ( # [ source] anyhow:: Error ) ,
25
+ #[ snafu ( display ( "Remote has reset the connection" ) ) ]
26
+ RemoteReset { source : anyhow:: Error } ,
14
27
/// Remote behaved in a non-compliant way.
15
- #[ error ( "Remote behaved in a non-compliant way" ) ]
16
- NoncompliantNode ( # [ source] anyhow:: Error ) ,
28
+ #[ snafu ( display ( "Remote behaved in a non-compliant way" ) ) ]
29
+ NoncompliantNode { source : anyhow:: Error } ,
17
30
18
31
/// Network or IO operation failed.
19
- #[ error ( "A network or IO operation failed" ) ]
20
- Io ( # [ source] anyhow:: Error ) ,
32
+ #[ snafu ( display ( "A network or IO operation failed" ) ) ]
33
+ Io { source : anyhow:: Error } ,
21
34
22
35
/// Our download request is invalid.
23
- #[ error ( "Our download request is invalid" ) ]
24
- BadRequest ( # [ source] anyhow:: Error ) ,
36
+ #[ snafu ( display ( "Our download request is invalid" ) ) ]
37
+ BadRequest { source : anyhow:: Error } ,
25
38
/// Operation failed on the local node.
26
- #[ error ( "Operation failed on the local node" ) ]
27
- LocalFailure ( # [ source] anyhow:: Error ) ,
39
+ #[ snafu ( display ( "Operation failed on the local node" ) ) ]
40
+ LocalFailure { source : anyhow:: Error } ,
28
41
}
29
42
30
43
pub type GetResult < T > = std:: result:: Result < T , GetError > ;
31
44
32
45
impl From < irpc:: channel:: SendError > for GetError {
33
46
fn from ( value : irpc:: channel:: SendError ) -> Self {
34
- Self :: LocalFailure ( value. into ( ) )
47
+ Self :: LocalFailure {
48
+ source : value. into ( ) ,
49
+ }
35
50
}
36
51
}
37
52
38
53
impl < T : Send + Sync + ' static > From < tokio:: sync:: mpsc:: error:: SendError < T > > for GetError {
39
54
fn from ( value : tokio:: sync:: mpsc:: error:: SendError < T > ) -> Self {
40
- Self :: LocalFailure ( value. into ( ) )
55
+ Self :: LocalFailure {
56
+ source : value. into ( ) ,
57
+ }
41
58
}
42
59
}
43
60
@@ -49,40 +66,40 @@ impl From<endpoint::ConnectionError> for GetError {
49
66
e @ ConnectionError :: VersionMismatch => {
50
67
// > The peer doesn't implement any supported version
51
68
// unsupported version is likely a long time error, so this peer is not usable
52
- GetError :: NoncompliantNode ( e. into ( ) )
69
+ GetError :: NoncompliantNode { source : e. into ( ) }
53
70
}
54
71
e @ ConnectionError :: TransportError ( _) => {
55
72
// > The peer violated the QUIC specification as understood by this implementation
56
73
// bad peer we don't want to keep around
57
- GetError :: NoncompliantNode ( e. into ( ) )
74
+ GetError :: NoncompliantNode { source : e. into ( ) }
58
75
}
59
76
e @ ConnectionError :: ConnectionClosed ( _) => {
60
77
// > The peer's QUIC stack aborted the connection automatically
61
78
// peer might be disconnecting or otherwise unavailable, drop it
62
- GetError :: Io ( e. into ( ) )
79
+ GetError :: Io { source : e. into ( ) }
63
80
}
64
81
e @ ConnectionError :: ApplicationClosed ( _) => {
65
82
// > The peer closed the connection
66
83
// peer might be disconnecting or otherwise unavailable, drop it
67
- GetError :: Io ( e. into ( ) )
84
+ GetError :: Io { source : e. into ( ) }
68
85
}
69
86
e @ ConnectionError :: Reset => {
70
87
// > The peer is unable to continue processing this connection, usually due to having restarted
71
- GetError :: RemoteReset ( e. into ( ) )
88
+ GetError :: RemoteReset { source : e. into ( ) }
72
89
}
73
90
e @ ConnectionError :: TimedOut => {
74
91
// > Communication with the peer has lapsed for longer than the negotiated idle timeout
75
- GetError :: Io ( e. into ( ) )
92
+ GetError :: Io { source : e. into ( ) }
76
93
}
77
94
e @ ConnectionError :: LocallyClosed => {
78
95
// > The local application closed the connection
79
96
// TODO(@divma): don't see how this is reachable but let's just not use the peer
80
- GetError :: Io ( e. into ( ) )
97
+ GetError :: Io { source : e. into ( ) }
81
98
}
82
99
e @ ConnectionError :: CidsExhausted => {
83
100
// > The connection could not be created because not enough of the CID space
84
101
// > is available
85
- GetError :: Io ( e. into ( ) )
102
+ GetError :: Io { source : e. into ( ) }
86
103
}
87
104
}
88
105
}
@@ -92,32 +109,38 @@ impl From<endpoint::ReadError> for GetError {
92
109
fn from ( value : endpoint:: ReadError ) -> Self {
93
110
use endpoint:: ReadError ;
94
111
match value {
95
- e @ ReadError :: Reset ( _) => GetError :: RemoteReset ( e. into ( ) ) ,
112
+ e @ ReadError :: Reset ( _) => GetError :: RemoteReset { source : e. into ( ) } ,
96
113
ReadError :: ConnectionLost ( conn_error) => conn_error. into ( ) ,
97
114
ReadError :: ClosedStream
98
115
| ReadError :: IllegalOrderedRead
99
116
| ReadError :: ZeroRttRejected => {
100
117
// all these errors indicate the peer is not usable at this moment
101
- GetError :: Io ( value. into ( ) )
118
+ GetError :: Io {
119
+ source : value. into ( ) ,
120
+ }
102
121
}
103
122
}
104
123
}
105
124
}
106
125
impl From < ClosedStream > for GetError {
107
126
fn from ( value : ClosedStream ) -> Self {
108
- GetError :: Io ( value. into ( ) )
127
+ GetError :: Io {
128
+ source : value. into ( ) ,
129
+ }
109
130
}
110
131
}
111
132
112
133
impl From < quinn:: WriteError > for GetError {
113
134
fn from ( value : quinn:: WriteError ) -> Self {
114
135
use quinn:: WriteError ;
115
136
match value {
116
- e @ WriteError :: Stopped ( _) => GetError :: RemoteReset ( e. into ( ) ) ,
137
+ e @ WriteError :: Stopped ( _) => GetError :: RemoteReset { source : e. into ( ) } ,
117
138
WriteError :: ConnectionLost ( conn_error) => conn_error. into ( ) ,
118
139
WriteError :: ClosedStream | WriteError :: ZeroRttRejected => {
119
140
// all these errors indicate the peer is not usable at this moment
120
- GetError :: Io ( value. into ( ) )
141
+ GetError :: Io {
142
+ source : value. into ( ) ,
143
+ }
121
144
}
122
145
}
123
146
}
@@ -129,17 +152,17 @@ impl From<crate::get::fsm::ConnectedNextError> for GetError {
129
152
match value {
130
153
e @ PostcardSer { .. } => {
131
154
// serialization errors indicate something wrong with the request itself
132
- GetError :: BadRequest ( e. into ( ) )
155
+ GetError :: BadRequest { source : e. into ( ) }
133
156
}
134
157
e @ RequestTooBig { .. } => {
135
158
// request will never be sent, drop it
136
- GetError :: BadRequest ( e. into ( ) )
159
+ GetError :: BadRequest { source : e. into ( ) }
137
160
}
138
161
Write { source, .. } => source. into ( ) ,
139
162
Closed { source, .. } => source. into ( ) ,
140
163
e @ Io { .. } => {
141
164
// io errors are likely recoverable
142
- GetError :: Io ( e. into ( ) )
165
+ GetError :: Io { source : e. into ( ) }
143
166
}
144
167
}
145
168
}
@@ -149,15 +172,23 @@ impl From<crate::get::fsm::AtBlobHeaderNextError> for GetError {
149
172
fn from ( value : crate :: get:: fsm:: AtBlobHeaderNextError ) -> Self {
150
173
use crate :: get:: fsm:: AtBlobHeaderNextError :: * ;
151
174
match value {
152
- e @ NotFound { .. } => {
175
+ NotFound {
176
+ backtrace,
177
+ span_trace,
178
+ } => {
153
179
// > This indicates that the provider does not have the requested data.
154
180
// peer might have the data later, simply retry it
155
- GetError :: NotFound ( e. into ( ) )
181
+ GetError :: NotFound {
182
+ source : GetNotFoundError :: AtBlobHeader {
183
+ backtrace,
184
+ span_trace,
185
+ } ,
186
+ }
156
187
}
157
188
EndpointRead { source, .. } => source. into ( ) ,
158
189
e @ Io { .. } => {
159
190
// io errors are likely recoverable
160
- GetError :: Io ( e. into ( ) )
191
+ GetError :: Io { source : e. into ( ) }
161
192
}
162
193
}
163
194
}
@@ -168,18 +199,44 @@ impl From<crate::get::fsm::DecodeError> for GetError {
168
199
use crate :: get:: fsm:: DecodeError :: * ;
169
200
170
201
match value {
171
- e @ ChunkNotFound { .. } => GetError :: NotFound ( e. into ( ) ) ,
172
- e @ ParentNotFound { .. } => GetError :: NotFound ( e. into ( ) ) ,
173
- e @ LeafNotFound { .. } => GetError :: NotFound ( e. into ( ) ) ,
202
+ ChunkNotFound {
203
+ backtrace,
204
+ span_trace,
205
+ } => GetError :: NotFound {
206
+ source : GetNotFoundError :: AtBlobHeader {
207
+ backtrace,
208
+ span_trace,
209
+ } ,
210
+ } ,
211
+ ParentNotFound {
212
+ backtrace,
213
+ span_trace,
214
+ ..
215
+ } => GetError :: NotFound {
216
+ source : GetNotFoundError :: AtBlobHeader {
217
+ backtrace,
218
+ span_trace,
219
+ } ,
220
+ } ,
221
+ LeafNotFound {
222
+ backtrace,
223
+ span_trace,
224
+ ..
225
+ } => GetError :: NotFound {
226
+ source : GetNotFoundError :: AtBlobHeader {
227
+ backtrace,
228
+ span_trace,
229
+ } ,
230
+ } ,
174
231
e @ ParentHashMismatch { .. } => {
175
232
// TODO(@divma): did the peer sent wrong data? is it corrupted? did we sent a wrong
176
233
// request?
177
- GetError :: NoncompliantNode ( e. into ( ) )
234
+ GetError :: NoncompliantNode { source : e. into ( ) }
178
235
}
179
236
e @ LeafHashMismatch { .. } => {
180
237
// TODO(@divma): did the peer sent wrong data? is it corrupted? did we sent a wrong
181
238
// request?
182
- GetError :: NoncompliantNode ( e. into ( ) )
239
+ GetError :: NoncompliantNode { source : e. into ( ) }
183
240
}
184
241
Read { source, .. } => source. into ( ) ,
185
242
DecodeIo { source, .. } => source. into ( ) ,
@@ -191,6 +248,8 @@ impl From<std::io::Error> for GetError {
191
248
fn from ( value : std:: io:: Error ) -> Self {
192
249
// generally consider io errors recoverable
193
250
// we might want to revisit this at some point
194
- GetError :: Io ( value. into ( ) )
251
+ GetError :: Io {
252
+ source : value. into ( ) ,
253
+ }
195
254
}
196
255
}
0 commit comments