From 1fe932d07fbf492df61d978acf6c2f99f070d910 Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Sat, 1 Nov 2025 17:20:39 +0100 Subject: [PATCH] migrate to this error it doesn't generate a bazillion warning at compile time --- Cargo.lock | 58 ++++++----------------- Cargo.toml | 3 +- src/api/admin/Cargo.toml | 2 +- src/api/admin/error.rs | 21 ++++----- src/api/common/Cargo.toml | 2 +- src/api/common/common_error.rs | 30 ++++++------ src/api/common/signature/error.rs | 12 ++--- src/api/k2v/Cargo.toml | 2 +- src/api/k2v/error.rs | 24 +++++----- src/api/s3/Cargo.toml | 2 +- src/api/s3/error.rs | 46 ++++++++++-------- src/db/Cargo.toml | 2 +- src/db/lib.rs | 6 +-- src/model/Cargo.toml | 2 +- src/model/garage.rs | 6 +-- src/model/helper/error.rs | 14 +++--- src/net/Cargo.toml | 2 +- src/net/endpoint.rs | 4 +- src/net/error.rs | 44 +++++++++--------- src/rpc/Cargo.toml | 4 +- src/rpc/consul.rs | 16 +++---- src/util/Cargo.toml | 2 +- src/util/error.rs | 77 ++++++++++++++----------------- src/web/Cargo.toml | 2 +- src/web/error.rs | 8 ++-- 25 files changed, 177 insertions(+), 214 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1a5e86c..ec4b80bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1113,20 +1113,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "err-derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34a887c8df3ed90498c1c437ce21f211c8e27672921a8ffa293cb8d6d4caa9e" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", - "synstructure 0.12.6", -] - [[package]] name = "errno" version = "0.3.10" @@ -1356,7 +1342,6 @@ dependencies = [ "async-trait", "bytesize", "chrono", - "err-derive", "format_table", "futures", "garage_api_common", @@ -1374,6 +1359,7 @@ dependencies = [ "prometheus", "serde", "serde_json", + "thiserror 2.0.12", "tokio", "tracing", "url", @@ -1389,7 +1375,6 @@ dependencies = [ "chrono", "crc-fast", "crypto-common", - "err-derive", "futures", "garage_model", "garage_table", @@ -1408,6 +1393,7 @@ dependencies = [ "serde_json", "sha1", "sha2", + "thiserror 2.0.12", "tokio", "tracing", "url", @@ -1418,7 +1404,6 @@ name = "garage_api_k2v" version = "2.1.0" dependencies = [ "base64 0.21.7", - "err-derive", "futures", "garage_api_common", "garage_model", @@ -1431,6 +1416,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", + "thiserror 2.0.12", "tokio", "tracing", "url", @@ -1446,7 +1432,6 @@ dependencies = [ "bytes", "chrono", "crc-fast", - "err-derive", "form_urlencoded", "futures", "garage_api_common", @@ -1474,6 +1459,7 @@ dependencies = [ "serde_json", "sha1", "sha2", + "thiserror 2.0.12", "tokio", "tokio-stream", "tokio-util 0.7.14", @@ -1509,7 +1495,6 @@ dependencies = [ name = "garage_db" version = "2.1.0" dependencies = [ - "err-derive", "fjall", "heed", "mktemp", @@ -1517,6 +1502,7 @@ dependencies = [ "r2d2", "r2d2_sqlite", "rusqlite", + "thiserror 2.0.12", "tracing", ] @@ -1529,7 +1515,6 @@ dependencies = [ "base64 0.21.7", "blake2", "chrono", - "err-derive", "futures", "garage_block", "garage_db", @@ -1543,6 +1528,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_bytes", + "thiserror 2.0.12", "tokio", "tracing", "zstd", @@ -1555,7 +1541,6 @@ dependencies = [ "arc-swap", "bytes", "cfg-if", - "err-derive", "futures", "hex", "kuska-handshake", @@ -1568,6 +1553,7 @@ dependencies = [ "rand 0.8.5", "rmp-serde", "serde", + "thiserror 2.0.12", "tokio", "tokio-stream", "tokio-util 0.7.14", @@ -1580,7 +1566,6 @@ dependencies = [ "arc-swap", "async-trait", "bytesize", - "err-derive", "format_table", "futures", "garage_net", @@ -1601,6 +1586,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", + "thiserror 2.0.12", "tokio", "tracing", ] @@ -1635,7 +1621,6 @@ dependencies = [ "blake2", "bytesize", "chrono", - "err-derive", "futures", "garage_db", "garage_net", @@ -1652,6 +1637,7 @@ dependencies = [ "serde", "serde_json", "sha2", + "thiserror 2.0.12", "tokio", "toml", "tracing", @@ -1662,7 +1648,6 @@ dependencies = [ name = "garage_web" version = "2.1.0" dependencies = [ - "err-derive", "garage_api_common", "garage_api_s3", "garage_model", @@ -1673,6 +1658,7 @@ dependencies = [ "hyper 1.6.0", "opentelemetry", "percent-encoding", + "thiserror 2.0.12", "tokio", "tracing", ] @@ -2465,7 +2451,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tracing-subscriber", ] @@ -4282,18 +4268,6 @@ dependencies = [ "crossbeam-queue", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -4813,12 +4787,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "universal-hash" version = "0.5.1" @@ -5344,7 +5312,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.100", - "synstructure 0.13.1", + "synstructure", ] [[package]] @@ -5405,7 +5373,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.100", - "synstructure 0.13.1", + "synstructure", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9e206466..67fafe13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,6 @@ cfg-if = "1.0" chrono = { version = "0.4", features = ["serde"] } crc-fast = "1.1" crypto-common = "0.1" -err-derive = "0.3" gethostname = "0.4" git-version = "0.3.4" hex = "0.4" @@ -138,7 +137,7 @@ prometheus = "0.13" aws-sigv4 = { version = "1.1", default-features = false } hyper-rustls = { version = "0.26", default-features = false, features = ["http1", "http2", "ring", "rustls-native-certs"] } log = "0.4" -thiserror = "1.0" +thiserror = "2.0" # ---- used only as build / dev dependencies ---- assert-json-diff = "2.0" diff --git a/src/api/admin/Cargo.toml b/src/api/admin/Cargo.toml index 29371663..9f6c06b7 100644 --- a/src/api/admin/Cargo.toml +++ b/src/api/admin/Cargo.toml @@ -26,7 +26,7 @@ argon2.workspace = true async-trait.workspace = true bytesize.workspace = true chrono.workspace = true -err-derive.workspace = true +thiserror.workspace = true hex.workspace = true paste.workspace = true tracing.workspace = true diff --git a/src/api/admin/error.rs b/src/api/admin/error.rs index 70daf800..e35ebff6 100644 --- a/src/api/admin/error.rs +++ b/src/api/admin/error.rs @@ -1,6 +1,6 @@ use std::convert::TryFrom; -use err_derive::Error; +use thiserror::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; @@ -16,36 +16,33 @@ use garage_api_common::helpers::*; /// Errors of this crate #[derive(Debug, Error)] pub enum Error { - #[error(display = "{}", _0)] + #[error("{0}")] /// Error from common error - Common(#[error(source)] CommonError), + Common(#[from] CommonError), // Category: cannot process /// The admin API token does not exist - #[error(display = "Admin token not found: {}", _0)] + #[error("Admin token not found: {0}")] NoSuchAdminToken(String), /// The API access key does not exist - #[error(display = "Access key not found: {}", _0)] + #[error("Access key not found: {00}")] NoSuchAccessKey(String), /// The requested block does not exist - #[error(display = "Block not found: {}", _0)] + #[error("Block not found: {0}")] NoSuchBlock(String), /// The requested worker does not exist - #[error(display = "Worker not found: {}", _0)] + #[error("Worker not found: {0}")] NoSuchWorker(u64), /// The object requested don't exists - #[error(display = "Key not found")] + #[error("Key not found")] NoSuchKey, /// In Import key, the key already exists - #[error( - display = "Key {} already exists in data store. Even if it is deleted, we can't let you create a new key with the same ID. Sorry.", - _0 - )] + #[error("Key {0} already exists in data store. Even if it is deleted, we can't let you create a new key with the same ID. Sorry.")] KeyAlreadyExists(String), } diff --git a/src/api/common/Cargo.toml b/src/api/common/Cargo.toml index 6af35358..87901839 100644 --- a/src/api/common/Cargo.toml +++ b/src/api/common/Cargo.toml @@ -23,7 +23,7 @@ bytes.workspace = true chrono.workspace = true crc-fast.workspace = true crypto-common.workspace = true -err-derive.workspace = true +thiserror.workspace = true hex.workspace = true hmac.workspace = true md-5.workspace = true diff --git a/src/api/common/common_error.rs b/src/api/common/common_error.rs index 597a3511..1335fece 100644 --- a/src/api/common/common_error.rs +++ b/src/api/common/common_error.rs @@ -1,6 +1,6 @@ use std::convert::TryFrom; -use err_derive::Error; +use thiserror::Error; use hyper::StatusCode; use garage_util::error::Error as GarageError; @@ -12,48 +12,48 @@ use garage_model::helper::error::Error as HelperError; pub enum CommonError { // ---- INTERNAL ERRORS ---- /// Error related to deeper parts of Garage - #[error(display = "Internal error: {}", _0)] - InternalError(#[error(source)] GarageError), + #[error("Internal error: {0}")] + InternalError(#[from] GarageError), /// Error related to Hyper - #[error(display = "Internal error (Hyper error): {}", _0)] - Hyper(#[error(source)] hyper::Error), + #[error("Internal error (Hyper error): {0}")] + Hyper(#[from] hyper::Error), /// Error related to HTTP - #[error(display = "Internal error (HTTP error): {}", _0)] - Http(#[error(source)] http::Error), + #[error("Internal error (HTTP error): {0}")] + Http(#[from] http::Error), // ---- GENERIC CLIENT ERRORS ---- /// Proper authentication was not provided - #[error(display = "Forbidden: {}", _0)] + #[error("Forbidden: {0}")] Forbidden(String), /// Generic bad request response with custom message - #[error(display = "Bad request: {}", _0)] + #[error("Bad request: {0}")] BadRequest(String), /// The client sent a header with invalid value - #[error(display = "Invalid header value: {}", _0)] - InvalidHeader(#[error(source)] hyper::header::ToStrError), + #[error("Invalid header value: {0}")] + InvalidHeader(#[from] hyper::header::ToStrError), // ---- SPECIFIC ERROR CONDITIONS ---- // These have to be error codes referenced in the S3 spec here: // https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList /// The bucket requested don't exists - #[error(display = "Bucket not found: {}", _0)] + #[error("Bucket not found: {0}")] NoSuchBucket(String), /// Tried to create a bucket that already exist - #[error(display = "Bucket already exists")] + #[error("Bucket already exists")] BucketAlreadyExists, /// Tried to delete a non-empty bucket - #[error(display = "Tried to delete a non-empty bucket")] + #[error("Tried to delete a non-empty bucket")] BucketNotEmpty, // Category: bad request /// Bucket name is not valid according to AWS S3 specs - #[error(display = "Invalid bucket name: {}", _0)] + #[error("Invalid bucket name: {0}")] InvalidBucketName(String), } diff --git a/src/api/common/signature/error.rs b/src/api/common/signature/error.rs index b2f396b5..a1b353e1 100644 --- a/src/api/common/signature/error.rs +++ b/src/api/common/signature/error.rs @@ -1,4 +1,4 @@ -use err_derive::Error; +use thiserror::Error; use crate::common_error::CommonError; pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError}; @@ -6,21 +6,21 @@ pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInterna /// Errors of this crate #[derive(Debug, Error)] pub enum Error { - #[error(display = "{}", _0)] + #[error("{0}")] /// Error from common error Common(CommonError), /// Authorization Header Malformed - #[error(display = "Authorization header malformed, unexpected scope: {}", _0)] + #[error("Authorization header malformed, unexpected scope: {0}")] AuthorizationHeaderMalformed(String), // Category: bad request /// The request contained an invalid UTF-8 sequence in its path or in other parameters - #[error(display = "Invalid UTF-8: {}", _0)] - InvalidUtf8Str(#[error(source)] std::str::Utf8Error), + #[error("Invalid UTF-8: {0}")] + InvalidUtf8Str(#[from] std::str::Utf8Error), /// The provided digest (checksum) value was invalid - #[error(display = "Invalid digest: {}", _0)] + #[error("Invalid digest: {0}")] InvalidDigest(String), } diff --git a/src/api/k2v/Cargo.toml b/src/api/k2v/Cargo.toml index 187f3372..710898d0 100644 --- a/src/api/k2v/Cargo.toml +++ b/src/api/k2v/Cargo.toml @@ -20,7 +20,7 @@ garage_util = { workspace = true, features = [ "k2v" ] } garage_api_common.workspace = true base64.workspace = true -err-derive.workspace = true +thiserror.workspace = true tracing.workspace = true futures.workspace = true diff --git a/src/api/k2v/error.rs b/src/api/k2v/error.rs index 2aa777d0..431fc706 100644 --- a/src/api/k2v/error.rs +++ b/src/api/k2v/error.rs @@ -1,4 +1,4 @@ -use err_derive::Error; +use thiserror::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; @@ -14,38 +14,38 @@ use garage_api_common::signature::error::Error as SignatureError; /// Errors of this crate #[derive(Debug, Error)] pub enum Error { - #[error(display = "{}", _0)] + #[error("{0}")] /// Error from common error - Common(#[error(source)] CommonError), + Common(#[from] CommonError), // Category: cannot process /// Authorization Header Malformed - #[error(display = "Authorization header malformed, unexpected scope: {}", _0)] + #[error("Authorization header malformed, unexpected scope: {0}")] AuthorizationHeaderMalformed(String), /// The provided digest (checksum) value was invalid - #[error(display = "Invalid digest: {}", _0)] + #[error("Invalid digest: {0}")] InvalidDigest(String), /// The object requested don't exists - #[error(display = "Key not found")] + #[error("Key not found")] NoSuchKey, /// Some base64 encoded data was badly encoded - #[error(display = "Invalid base64: {}", _0)] - InvalidBase64(#[error(source)] base64::DecodeError), + #[error("Invalid base64: {0}")] + InvalidBase64(#[from] base64::DecodeError), /// Invalid causality token - #[error(display = "Invalid causality token")] + #[error("Invalid causality token")] InvalidCausalityToken, /// The client asked for an invalid return format (invalid Accept header) - #[error(display = "Not acceptable: {}", _0)] + #[error("Not acceptable: {0}")] NotAcceptable(String), /// The request contained an invalid UTF-8 sequence in its path or in other parameters - #[error(display = "Invalid UTF-8: {}", _0)] - InvalidUtf8Str(#[error(source)] std::str::Utf8Error), + #[error("Invalid UTF-8: {0}")] + InvalidUtf8Str(#[from] std::str::Utf8Error), } commonErrorDerivative!(Error); diff --git a/src/api/s3/Cargo.toml b/src/api/s3/Cargo.toml index d69e9f15..646e2ff5 100644 --- a/src/api/s3/Cargo.toml +++ b/src/api/s3/Cargo.toml @@ -28,7 +28,7 @@ base64.workspace = true bytes.workspace = true chrono.workspace = true crc-fast.workspace = true -err-derive.workspace = true +thiserror.workspace = true hex.workspace = true hmac.workspace = true tracing.workspace = true diff --git a/src/api/s3/error.rs b/src/api/s3/error.rs index 9fac25df..cca7dd6e 100644 --- a/src/api/s3/error.rs +++ b/src/api/s3/error.rs @@ -1,6 +1,6 @@ use std::convert::TryInto; -use err_derive::Error; +use thiserror::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; @@ -25,67 +25,67 @@ use crate::xml as s3_xml; /// Errors of this crate #[derive(Debug, Error)] pub enum Error { - #[error(display = "{}", _0)] + #[error("{0}")] /// Error from common error - Common(#[error(source)] CommonError), + Common(#[from] CommonError), // Category: cannot process /// Authorization Header Malformed - #[error(display = "Authorization header malformed, unexpected scope: {}", _0)] + #[error("Authorization header malformed, unexpected scope: {0}")] AuthorizationHeaderMalformed(String), /// The object requested don't exists - #[error(display = "Key not found")] + #[error("Key not found")] NoSuchKey, /// The multipart upload requested don't exists - #[error(display = "Upload not found")] + #[error("Upload not found")] NoSuchUpload, /// Precondition failed (e.g. x-amz-copy-source-if-match) - #[error(display = "At least one of the preconditions you specified did not hold")] + #[error("At least one of the preconditions you specified did not hold")] PreconditionFailed, /// Parts specified in CMU request do not match parts actually uploaded - #[error(display = "Parts given to CompleteMultipartUpload do not match uploaded parts")] + #[error("Parts given to CompleteMultipartUpload do not match uploaded parts")] InvalidPart, /// Parts given to CompleteMultipartUpload were not in ascending order - #[error(display = "Parts given to CompleteMultipartUpload were not in ascending order")] + #[error("Parts given to CompleteMultipartUpload were not in ascending order")] InvalidPartOrder, /// In CompleteMultipartUpload: not enough data /// (here we are more lenient than AWS S3) - #[error(display = "Proposed upload is smaller than the minimum allowed object size")] + #[error("Proposed upload is smaller than the minimum allowed object size")] EntityTooSmall, // Category: bad request /// The request contained an invalid UTF-8 sequence in its path or in other parameters - #[error(display = "Invalid UTF-8: {}", _0)] - InvalidUtf8Str(#[error(source)] std::str::Utf8Error), + #[error("Invalid UTF-8: {0}")] + InvalidUtf8Str(#[from] std::str::Utf8Error), /// The request used an invalid path - #[error(display = "Invalid UTF-8: {}", _0)] - InvalidUtf8String(#[error(source)] std::string::FromUtf8Error), + #[error("Invalid UTF-8: {0}")] + InvalidUtf8String(#[from] std::string::FromUtf8Error), /// The client sent invalid XML data - #[error(display = "Invalid XML: {}", _0)] + #[error("Invalid XML: {0}")] InvalidXml(String), /// The client sent a range header with invalid value - #[error(display = "Invalid HTTP range: {:?}", _0)] - InvalidRange(#[error(from)] (http_range::HttpRangeParseError, u64)), + #[error("Invalid HTTP range: {0:?}")] + InvalidRange((http_range::HttpRangeParseError, u64)), /// The client sent a range header with invalid value - #[error(display = "Invalid encryption algorithm: {:?}, should be AES256", _0)] + #[error("Invalid encryption algorithm: {0:?}, should be AES256")] InvalidEncryptionAlgorithm(String), /// The provided digest (checksum) value was invalid - #[error(display = "Invalid digest: {}", _0)] + #[error("Invalid digest: {0}")] InvalidDigest(String), /// The client sent a request for an action not supported by garage - #[error(display = "Unimplemented action: {}", _0)] + #[error("Unimplemented action: {0}")] NotImplemented(String), } @@ -99,6 +99,12 @@ impl From for Error { } } +impl From<(http_range::HttpRangeParseError, u64)> for Error { + fn from (err: (http_range::HttpRangeParseError, u64)) -> Error { + Error::InvalidRange(err) + } +} + impl From for Error { fn from(err: roxmltree::Error) -> Self { Self::InvalidXml(format!("{}", err)) diff --git a/src/db/Cargo.toml b/src/db/Cargo.toml index 33d3cc40..ab5a3940 100644 --- a/src/db/Cargo.toml +++ b/src/db/Cargo.toml @@ -12,7 +12,7 @@ readme = "../../README.md" path = "lib.rs" [dependencies] -err-derive.workspace = true +thiserror.workspace = true tracing.workspace = true heed = { workspace = true, optional = true } diff --git a/src/db/lib.rs b/src/db/lib.rs index 71826255..2a467c7c 100644 --- a/src/db/lib.rs +++ b/src/db/lib.rs @@ -20,7 +20,7 @@ use std::cell::Cell; use std::path::PathBuf; use std::sync::Arc; -use err_derive::Error; +use thiserror::Error; pub use open::*; @@ -44,7 +44,7 @@ pub type TxValueIter<'a> = Box); impl From for Error { @@ -56,7 +56,7 @@ impl From for Error { pub type Result = std::result::Result; #[derive(Debug, Error)] -#[error(display = "{}", _0)] +#[error("{0}")] pub struct TxOpError(pub(crate) Error); pub type TxOpResult = std::result::Result; diff --git a/src/model/Cargo.toml b/src/model/Cargo.toml index 48af8976..d989f17e 100644 --- a/src/model/Cargo.toml +++ b/src/model/Cargo.toml @@ -25,7 +25,7 @@ argon2.workspace = true async-trait.workspace = true blake2.workspace = true chrono.workspace = true -err-derive.workspace = true +thiserror.workspace = true hex.workspace = true http.workspace = true base64.workspace = true diff --git a/src/model/garage.rs b/src/model/garage.rs index 760be47d..4ba11bc5 100644 --- a/src/model/garage.rs +++ b/src/model/garage.rs @@ -321,15 +321,15 @@ impl Garage { Ok(()) } - pub fn bucket_helper(&self) -> helper::bucket::BucketHelper { + pub fn bucket_helper(&self) -> helper::bucket::BucketHelper<'_> { helper::bucket::BucketHelper(self) } - pub fn key_helper(&self) -> helper::key::KeyHelper { + pub fn key_helper(&self) -> helper::key::KeyHelper<'_> { helper::key::KeyHelper(self) } - pub async fn locked_helper(&self) -> helper::locked::LockedHelper { + pub async fn locked_helper(&self) -> helper::locked::LockedHelper<'_> { let lock = self.bucket_lock.lock().await; helper::locked::LockedHelper(self, Some(lock)) } diff --git a/src/model/helper/error.rs b/src/model/helper/error.rs index e2ffdd68..6a78546d 100644 --- a/src/model/helper/error.rs +++ b/src/model/helper/error.rs @@ -1,24 +1,24 @@ -use err_derive::Error; +use thiserror::Error; use serde::{Deserialize, Serialize}; use garage_util::error::Error as GarageError; #[derive(Debug, Error, Serialize, Deserialize)] pub enum Error { - #[error(display = "Internal error: {}", _0)] - Internal(#[error(source)] GarageError), + #[error("Internal error: {0}")] + Internal(#[from] GarageError), - #[error(display = "Bad request: {}", _0)] + #[error("Bad request: {0}")] BadRequest(String), /// Bucket name is not valid according to AWS S3 specs - #[error(display = "Invalid bucket name: {}", _0)] + #[error("Invalid bucket name: {0}")] InvalidBucketName(String), - #[error(display = "Access key not found: {}", _0)] + #[error("Access key not found: {0}")] NoSuchAccessKey(String), - #[error(display = "Bucket not found: {}", _0)] + #[error("Bucket not found: {0}")] NoSuchBucket(String), } diff --git a/src/net/Cargo.toml b/src/net/Cargo.toml index f973e288..c5cf0325 100644 --- a/src/net/Cargo.toml +++ b/src/net/Cargo.toml @@ -30,7 +30,7 @@ rand.workspace = true log.workspace = true arc-swap.workspace = true -err-derive.workspace = true +thiserror.workspace = true bytes.workspace = true cfg-if.workspace = true diff --git a/src/net/endpoint.rs b/src/net/endpoint.rs index d46acc42..3ab1048a 100644 --- a/src/net/endpoint.rs +++ b/src/net/endpoint.rs @@ -159,7 +159,7 @@ where pub(crate) type DynEndpoint = Box; pub(crate) trait GenericEndpoint { - fn handle(&self, req_enc: ReqEnc, from: NodeID) -> BoxFuture>; + fn handle(&self, req_enc: ReqEnc, from: NodeID) -> BoxFuture<'_, Result>; fn drop_handler(&self); fn clone_endpoint(&self) -> DynEndpoint; } @@ -175,7 +175,7 @@ where M: Message, H: StreamingEndpointHandler + 'static, { - fn handle(&self, req_enc: ReqEnc, from: NodeID) -> BoxFuture> { + fn handle(&self, req_enc: ReqEnc, from: NodeID) -> BoxFuture<'_, Result> { async move { match self.0.handler.load_full() { None => Err(Error::NoHandler), diff --git a/src/net/error.rs b/src/net/error.rs index cddb1eaa..899fe21c 100644 --- a/src/net/error.rs +++ b/src/net/error.rs @@ -1,49 +1,49 @@ use std::io; -use err_derive::Error; +use thiserror::Error; use log::error; #[derive(Debug, Error)] pub enum Error { - #[error(display = "IO error: {}", _0)] - Io(#[error(source)] io::Error), + #[error("IO error: {0}")] + Io(#[from] io::Error), - #[error(display = "Messagepack encode error: {}", _0)] - RMPEncode(#[error(source)] rmp_serde::encode::Error), - #[error(display = "Messagepack decode error: {}", _0)] - RMPDecode(#[error(source)] rmp_serde::decode::Error), + #[error("Messagepack encode error: {0}")] + RMPEncode(#[from] rmp_serde::encode::Error), + #[error("Messagepack decode error: {0}")] + RMPDecode(#[from] rmp_serde::decode::Error), - #[error(display = "Tokio join error: {}", _0)] - TokioJoin(#[error(source)] tokio::task::JoinError), + #[error("Tokio join error: {0}")] + TokioJoin(#[from] tokio::task::JoinError), - #[error(display = "oneshot receive error: {}", _0)] - OneshotRecv(#[error(source)] tokio::sync::oneshot::error::RecvError), + #[error("oneshot receive error: {0}")] + OneshotRecv(#[from] tokio::sync::oneshot::error::RecvError), - #[error(display = "Handshake error: {}", _0)] - Handshake(#[error(source)] kuska_handshake::async_std::Error), + #[error("Handshake error: {0}")] + Handshake(#[from] kuska_handshake::async_std::Error), - #[error(display = "UTF8 error: {}", _0)] - UTF8(#[error(source)] std::string::FromUtf8Error), + #[error("UTF8 error: {0}")] + UTF8(#[from] std::string::FromUtf8Error), - #[error(display = "Framing protocol error")] + #[error("Framing protocol error")] Framing, - #[error(display = "Remote error ({:?}): {}", _0, _1)] + #[error("Remote error ({0:?}): {1}")] Remote(io::ErrorKind, String), - #[error(display = "Request ID collision")] + #[error("Request ID collision")] IdCollision, - #[error(display = "{}", _0)] + #[error("{0}")] Message(String), - #[error(display = "No handler / shutting down")] + #[error("No handler / shutting down")] NoHandler, - #[error(display = "Connection closed")] + #[error("Connection closed")] ConnectionClosed, - #[error(display = "Version mismatch: {}", _0)] + #[error("Version mismatch: {0}")] VersionMismatch(String), } diff --git a/src/rpc/Cargo.toml b/src/rpc/Cargo.toml index 57fd0eb2..bab7194a 100644 --- a/src/rpc/Cargo.toml +++ b/src/rpc/Cargo.toml @@ -33,7 +33,7 @@ async-trait.workspace = true serde.workspace = true serde_bytes.workspace = true serde_json.workspace = true -err-derive = { workspace = true, optional = true } +thiserror = { workspace = true, optional = true } # newer version requires rust edition 2021 kube = { workspace = true, optional = true } @@ -49,5 +49,5 @@ opentelemetry.workspace = true [features] kubernetes-discovery = [ "kube", "k8s-openapi", "schemars" ] -consul-discovery = [ "reqwest", "err-derive" ] +consul-discovery = [ "reqwest", "thiserror" ] system-libs = [ "sodiumoxide/use-pkg-config" ] diff --git a/src/rpc/consul.rs b/src/rpc/consul.rs index f088bf3f..801e937f 100644 --- a/src/rpc/consul.rs +++ b/src/rpc/consul.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Read; use std::net::{IpAddr, SocketAddr}; -use err_derive::Error; +use thiserror::Error; use serde::{Deserialize, Serialize}; use garage_net::NodeID; @@ -219,12 +219,12 @@ impl ConsulDiscovery { /// Regroup all Consul discovery errors #[derive(Debug, Error)] pub enum ConsulError { - #[error(display = "IO error: {}", _0)] - Io(#[error(source)] std::io::Error), - #[error(display = "HTTP error: {}", _0)] - Reqwest(#[error(source)] reqwest::Error), - #[error(display = "Invalid Consul TLS configuration")] + #[error("IO error: {0}")] + Io(#[from] std::io::Error), + #[error("HTTP error: {0}")] + Reqwest(#[from] reqwest::Error), + #[error("Invalid Consul TLS configuration")] InvalidTLSConfig, - #[error(display = "Token error: {}", _0)] - Token(#[error(source)] reqwest::header::InvalidHeaderValue), + #[error("Token error: {0}")] + Token(#[from] reqwest::header::InvalidHeaderValue), } diff --git a/src/util/Cargo.toml b/src/util/Cargo.toml index 2a31b13c..cea82e50 100644 --- a/src/util/Cargo.toml +++ b/src/util/Cargo.toml @@ -21,7 +21,7 @@ arc-swap.workspace = true async-trait.workspace = true blake2.workspace = true bytesize.workspace = true -err-derive.workspace = true +thiserror.workspace = true hexdump.workspace = true xxhash-rust.workspace = true hex.workspace = true diff --git a/src/util/error.rs b/src/util/error.rs index d33bb19d..043d0dce 100644 --- a/src/util/error.rs +++ b/src/util/error.rs @@ -2,7 +2,7 @@ use std::fmt; use std::io; -use err_derive::Error; +use thiserror::Error; use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; @@ -12,71 +12,64 @@ use crate::encode::debug_serialize; /// Regroup all Garage errors #[derive(Debug, Error)] pub enum Error { - #[error(display = "IO error: {}", _0)] - Io(#[error(source)] io::Error), + #[error("IO error: {0}")] + Io(#[from] io::Error), - #[error(display = "Hyper error: {}", _0)] - Hyper(#[error(source)] hyper::Error), + #[error("Hyper error: {0}")] + Hyper(#[from] hyper::Error), - #[error(display = "HTTP error: {}", _0)] - Http(#[error(source)] http::Error), + #[error("HTTP error: {0}")] + Http(#[from] http::Error), - #[error(display = "Invalid HTTP header value: {}", _0)] - HttpHeader(#[error(source)] http::header::ToStrError), + #[error("Invalid HTTP header value: {0}")] + HttpHeader(#[from] http::header::ToStrError), - #[error(display = "Network error: {}", _0)] - Net(#[error(source)] garage_net::error::Error), + #[error("Network error: {0}")] + Net(#[from] garage_net::error::Error), - #[error(display = "DB error: {}", _0)] - Db(#[error(source)] garage_db::Error), + #[error("DB error: {0}")] + Db(#[from] garage_db::Error), - #[error(display = "Messagepack encode error: {}", _0)] - RmpEncode(#[error(source)] rmp_serde::encode::Error), - #[error(display = "Messagepack decode error: {}", _0)] - RmpDecode(#[error(source)] rmp_serde::decode::Error), - #[error(display = "JSON error: {}", _0)] - Json(#[error(source)] serde_json::error::Error), - #[error(display = "TOML decode error: {}", _0)] - TomlDecode(#[error(source)] toml::de::Error), + #[error("Messagepack encode error: {0}")] + RmpEncode(#[from] rmp_serde::encode::Error), + #[error("Messagepack decode error: {0}")] + RmpDecode(#[from] rmp_serde::decode::Error), + #[error("JSON error: {0}")] + Json(#[from] serde_json::error::Error), + #[error("TOML decode error: {0}")] + TomlDecode(#[from] toml::de::Error), - #[error(display = "Tokio join error: {}", _0)] - TokioJoin(#[error(source)] tokio::task::JoinError), + #[error("Tokio join error: {0}")] + TokioJoin(#[from] tokio::task::JoinError), - #[error(display = "Tokio semaphore acquire error: {}", _0)] - TokioSemAcquire(#[error(source)] tokio::sync::AcquireError), + #[error("Tokio semaphore acquire error: {0}")] + TokioSemAcquire(#[from] tokio::sync::AcquireError), - #[error(display = "Tokio broadcast receive error: {}", _0)] - TokioBcastRecv(#[error(source)] tokio::sync::broadcast::error::RecvError), + #[error("Tokio broadcast receive error: {0}")] + TokioBcastRecv(#[from] tokio::sync::broadcast::error::RecvError), - #[error(display = "Remote error: {}", _0)] + #[error("Remote error: {0}")] RemoteError(String), - #[error(display = "Timeout")] + #[error("Timeout")] Timeout, - #[error(display = "Layout not ready")] + #[error("Layout not ready")] LayoutNotReady, - #[error( - display = "Could not reach quorum of {} (sets={:?}). {} of {} request succeeded, others returned errors: {:?}", - _0, - _1, - _2, - _3, - _4 - )] + #[error("Could not reach quorum of {0} (sets={1:?}). {2} of {3} request succeeded, others returned errors: {4:?}")] Quorum(usize, Option, usize, usize, Vec), - #[error(display = "Unexpected RPC message: {}", _0)] + #[error("Unexpected RPC message: {0}")] UnexpectedRpcMessage(String), - #[error(display = "Corrupt data: does not match hash {:?}", _0)] + #[error("Corrupt data: does not match hash {0:?}")] CorruptData(Hash), - #[error(display = "Missing block {:?}: no node returned a valid block", _0)] + #[error("Missing block {0:?}: no node returned a valid block")] MissingBlock(Hash), - #[error(display = "{}", _0)] + #[error("{0}")] Message(String), } diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml index 0501f299..e29362c2 100644 --- a/src/web/Cargo.toml +++ b/src/web/Cargo.toml @@ -20,7 +20,7 @@ garage_model.workspace = true garage_util.workspace = true garage_table.workspace = true -err-derive.workspace = true +thiserror.workspace = true tracing.workspace = true percent-encoding.workspace = true diff --git a/src/web/error.rs b/src/web/error.rs index 7e6d4542..49650b1d 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -1,4 +1,4 @@ -use err_derive::Error; +use thiserror::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; @@ -8,15 +8,15 @@ use garage_api_common::generic_server::ApiError; #[derive(Debug, Error)] pub enum Error { /// An error received from the API crate - #[error(display = "API error: {}", _0)] + #[error("API error: {0}")] ApiError(garage_api_s3::error::Error), /// The file does not exist - #[error(display = "Not found")] + #[error("Not found")] NotFound, /// The client sent a request without host, or with unsupported method - #[error(display = "Bad request: {}", _0)] + #[error("Bad request: {0}")] BadRequest(String), }