Skip to content

Commit 0d855cb

Browse files
committed
Add sources to auto error conversion
1 parent edeef58 commit 0d855cb

4 files changed

Lines changed: 76 additions & 25 deletions

File tree

nativelink-error/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ load(
44
"rust_doc_test",
55
"rust_library",
66
"rust_test",
7+
"rust_test_suite",
78
)
89

910
rust_library(
@@ -29,6 +30,18 @@ rust_library(
2930
],
3031
)
3132

33+
rust_test_suite(
34+
name = "integration",
35+
timeout = "short",
36+
srcs = [
37+
"tests/error_tests.rs",
38+
],
39+
deps = [
40+
"//nativelink-error",
41+
"@crates//:walkdir",
42+
],
43+
)
44+
3245
rust_test(
3346
name = "unit_test",
3447
timeout = "short",

nativelink-error/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ lints.workspace = true
55
autobenches = false
66
autobins = false
77
autoexamples = false
8-
autotests = false
98
edition = "2024"
109
name = "nativelink-error"
1110
version = "1.0.0-rc4"
@@ -15,7 +14,9 @@ nativelink-metric = { path = "../nativelink-metric" }
1514
nativelink-proto = { path = "../nativelink-proto" }
1615

1716
prost = { version = "0.13.5", default-features = false }
18-
prost-types = { version = "0.13.5", default-features = false }
17+
prost-types = { version = "0.13.5", default-features = false, features = [
18+
"std",
19+
] }
1920
redis = { version = "1.0.0", default-features = false }
2021
rustls-pki-types = { version = "1.13.1", default-features = false }
2122
serde = { version = "1.0.219", default-features = false }
@@ -31,5 +32,5 @@ tonic = { version = "0.13.0", features = [
3132
"transport",
3233
], default-features = false }
3334
url = { version = "2.5.7", default-features = false }
34-
uuid = { version = "1.16.0", default-features = false }
35+
uuid = { version = "1.16.0", default-features = false, features = ["std"] }
3536
walkdir = { version = "2.5.0", default-features = false }

nativelink-error/src/lib.rs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ impl Error {
8383
}
8484
}
8585

86+
#[must_use]
87+
pub fn from_std_err(code: Code, mut err: &dyn core::error::Error) -> Self {
88+
let mut messages = vec![format!("{err}")];
89+
while let Some(src) = err.source() {
90+
messages.push(format!("{src}"));
91+
err = src;
92+
}
93+
messages.reverse();
94+
Self::new_with_messages(code, messages)
95+
}
96+
8697
#[inline]
8798
#[must_use]
8899
pub fn append<S: Into<String>>(mut self, msg: S) -> Self {
@@ -162,37 +173,37 @@ impl core::fmt::Display for Error {
162173

163174
impl From<prost::DecodeError> for Error {
164175
fn from(err: prost::DecodeError) -> Self {
165-
make_err!(Code::Internal, "{}", err.to_string())
176+
Self::from_std_err(Code::Internal, &err)
166177
}
167178
}
168179

169180
impl From<prost::EncodeError> for Error {
170181
fn from(err: prost::EncodeError) -> Self {
171-
make_err!(Code::Internal, "{}", err.to_string())
182+
Self::from_std_err(Code::Internal, &err)
172183
}
173184
}
174185

175186
impl From<prost::UnknownEnumValue> for Error {
176187
fn from(err: prost::UnknownEnumValue) -> Self {
177-
make_err!(Code::Internal, "{}", err.to_string())
188+
Self::from_std_err(Code::Internal, &err)
178189
}
179190
}
180191

181192
impl From<core::num::TryFromIntError> for Error {
182193
fn from(err: core::num::TryFromIntError) -> Self {
183-
make_err!(Code::InvalidArgument, "{}", err.to_string())
194+
Self::from_std_err(Code::InvalidArgument, &err)
184195
}
185196
}
186197

187198
impl From<tokio::task::JoinError> for Error {
188199
fn from(err: tokio::task::JoinError) -> Self {
189-
make_err!(Code::Internal, "{}", err.to_string())
200+
Self::from_std_err(Code::Internal, &err)
190201
}
191202
}
192203

193204
impl<T> From<PoisonError<MutexGuard<'_, T>>> for Error {
194205
fn from(err: PoisonError<MutexGuard<'_, T>>) -> Self {
195-
make_err!(Code::Internal, "{}", err.to_string())
206+
Self::from_std_err(Code::Internal, &err)
196207
}
197208
}
198209

@@ -209,7 +220,7 @@ impl From<serde_json5::Error> for Error {
209220
msg
210221
)
211222
} else {
212-
make_err!(Code::Internal, "{}", msg)
223+
Self::new(Code::Internal, msg)
213224
}
214225
}
215226
}
@@ -218,7 +229,7 @@ impl From<serde_json5::Error> for Error {
218229

219230
impl From<core::num::ParseIntError> for Error {
220231
fn from(err: core::num::ParseIntError) -> Self {
221-
make_err!(Code::InvalidArgument, "{}", err.to_string())
232+
Self::from_std_err(Code::InvalidArgument, &err)
222233
}
223234
}
224235

@@ -231,19 +242,19 @@ impl From<core::convert::Infallible> for Error {
231242

232243
impl From<TimestampError> for Error {
233244
fn from(err: TimestampError) -> Self {
234-
make_err!(Code::InvalidArgument, "{}", err)
245+
Self::from_std_err(Code::InvalidArgument, &err)
235246
}
236247
}
237248

238249
impl From<AcquireError> for Error {
239250
fn from(err: AcquireError) -> Self {
240-
make_err!(Code::Internal, "{}", err)
251+
Self::from_std_err(Code::Internal, &err)
241252
}
242253
}
243254

244255
impl From<Utf8Error> for Error {
245256
fn from(err: Utf8Error) -> Self {
246-
make_err!(Code::Internal, "{}", err)
257+
Self::from_std_err(Code::Internal, &err)
247258
}
248259
}
249260

@@ -284,7 +295,7 @@ impl From<redis::RedisError> for Error {
284295

285296
impl From<tonic::Status> for Error {
286297
fn from(status: tonic::Status) -> Self {
287-
make_err!(status.code(), "{}", status.to_string())
298+
Self::new(status.code(), status.to_string())
288299
}
289300
}
290301

@@ -295,32 +306,32 @@ impl From<Error> for tonic::Status {
295306
}
296307

297308
impl From<walkdir::Error> for Error {
298-
fn from(value: walkdir::Error) -> Self {
299-
Self::new(Code::Internal, value.to_string())
309+
fn from(err: walkdir::Error) -> Self {
310+
Self::from_std_err(Code::Internal, &err)
300311
}
301312
}
302313

303314
impl From<uuid::Error> for Error {
304-
fn from(value: uuid::Error) -> Self {
305-
Self::new(Code::Internal, value.to_string())
315+
fn from(err: uuid::Error) -> Self {
316+
Self::from_std_err(Code::Internal, &err)
306317
}
307318
}
308319

309320
impl From<rustls_pki_types::pem::Error> for Error {
310-
fn from(value: rustls_pki_types::pem::Error) -> Self {
311-
Self::new(Code::Internal, value.to_string())
321+
fn from(err: rustls_pki_types::pem::Error) -> Self {
322+
Self::from_std_err(Code::Internal, &err)
312323
}
313324
}
314325

315326
impl From<tokio::time::error::Elapsed> for Error {
316-
fn from(value: tokio::time::error::Elapsed) -> Self {
317-
Self::new(Code::DeadlineExceeded, value.to_string())
327+
fn from(err: tokio::time::error::Elapsed) -> Self {
328+
Self::from_std_err(Code::DeadlineExceeded, &err)
318329
}
319330
}
320331

321332
impl From<url::ParseError> for Error {
322-
fn from(value: url::ParseError) -> Self {
323-
Self::new(Code::Internal, value.to_string())
333+
fn from(err: url::ParseError) -> Self {
334+
Self::from_std_err(Code::Internal, &err)
324335
}
325336
}
326337

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use nativelink_error::Error;
2+
use walkdir::WalkDir;
3+
4+
#[test]
5+
fn walkdir_source_error() {
6+
for entry in WalkDir::new("/bad/path") {
7+
let err: Error = entry.unwrap_err().into();
8+
let os_error = {
9+
#[cfg(unix)]
10+
{
11+
"No such file or directory (os error 2)"
12+
}
13+
#[cfg(windows)]
14+
{
15+
"The system cannot find the path specified. (os error 3)"
16+
}
17+
};
18+
assert_eq!(
19+
err.messages,
20+
vec![
21+
os_error,
22+
&format!("IO error for operation on /bad/path: {os_error}")
23+
]
24+
);
25+
}
26+
}

0 commit comments

Comments
 (0)