From 47f63aead1bf836d76cd66cf6dcd64cad8339db4 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Sun, 6 Dec 2020 00:23:42 +1100 Subject: [PATCH] Replace failure with thiserror --- Cargo.toml | 9 +- README.md | 2 - src/backend/impl_lmdb/arch_migrator_error.rs | 70 ++++------- src/error.rs | 119 +++++++------------ 4 files changed, 65 insertions(+), 135 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 95d10834..558bd61c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ repository = "https://github.com/mozilla/rkv" version = "0.16.1" [features] -backtrace = ["failure/backtrace", "failure/std"] db-dup-sort = [] db-int-key = [] default = ["db-dup-sort", "db-int-key"] @@ -41,16 +40,10 @@ ordered-float = "1.0.1" paste = "0.1.11" serde = {version = "1.0", features = ["derive", "rc"]} serde_derive = "1.0" +thiserror = "1.0" url = "2.0" uuid = "0.8" -# Get rid of failure's dependency on backtrace. Eventually -# backtrace will move into Rust core, but we don't need it here. -[dependencies.failure] -default_features = false -features = ["derive"] -version = "0.1" - [dev-dependencies] byteorder = "1" tempfile = "3" diff --git a/README.md b/README.md index 59383a4d..5399299e 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,6 @@ There are several features that you can opt-in and out of when using rkv: By default, `db-dup-sort` and `db-int-key` features offer high level database APIs which allow multiple values per key, and optimizations around integer-based keys respectively. Opt out of these default features when specifying the rkv dependency in your Cargo.toml file to disable them; doing so avoids a certain amount of overhead required to support them. -If you specify the `backtrace` feature, backtraces will be enabled in "failure" errors. This feature is disabled by default. - To aid fuzzing efforts, `with-asan`, `with-fuzzer`, and `with-fuzzer-no-link` configure the build scripts responsible with compiling the underlying backing engines (e.g. LMDB) to build with these LLMV features enabled. Please refer to the official LLVM/Clang documentation on them for more informatiuon. These features are also disabled by default. ## Test diff --git a/src/backend/impl_lmdb/arch_migrator_error.rs b/src/backend/impl_lmdb/arch_migrator_error.rs index 7b56f5e9..c51b62be 100644 --- a/src/backend/impl_lmdb/arch_migrator_error.rs +++ b/src/backend/impl_lmdb/arch_migrator_error.rs @@ -14,78 +14,60 @@ use std::{ str, }; -use failure::Fail; +use thiserror::Error; -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum MigrateError { - #[fail(display = "database not found: {:?}", _0)] + #[error("database not found: {0:?}")] DatabaseNotFound(String), - #[fail(display = "{}", _0)] + #[error("{0}")] FromString(String), - #[fail(display = "couldn't determine bit depth")] + #[error("couldn't determine bit depth")] IndeterminateBitDepth, - #[fail(display = "I/O error: {:?}", _0)] - IoError(io::Error), + #[error("I/O error: {0:?}")] + IoError(#[from] io::Error), - #[fail(display = "invalid DatabaseFlags bits")] + #[error("invalid DatabaseFlags bits")] InvalidDatabaseBits, - #[fail(display = "invalid data version")] + #[error("invalid data version")] InvalidDataVersion, - #[fail(display = "invalid magic number")] + #[error("invalid magic number")] InvalidMagicNum, - #[fail(display = "invalid NodeFlags bits")] + #[error("invalid NodeFlags bits")] InvalidNodeBits, - #[fail(display = "invalid PageFlags bits")] + #[error("invalid PageFlags bits")] InvalidPageBits, - #[fail(display = "invalid page number")] + #[error("invalid page number")] InvalidPageNum, - #[fail(display = "lmdb backend error: {}", _0)] - LmdbError(lmdb::Error), + #[error("lmdb backend error: {0}")] + LmdbError(#[from] lmdb::Error), - #[fail(display = "string conversion error")] + #[error("string conversion error")] StringConversionError, - #[fail(display = "TryFromInt error: {:?}", _0)] - TryFromIntError(num::TryFromIntError), + #[error("TryFromInt error: {0:?}")] + TryFromIntError(#[from] num::TryFromIntError), - #[fail(display = "unexpected Page variant")] + #[error("unexpected Page variant")] UnexpectedPageVariant, - #[fail(display = "unexpected PageHeader variant")] + #[error("unexpected PageHeader variant")] UnexpectedPageHeaderVariant, - #[fail(display = "unsupported PageHeader variant")] + #[error("unsupported PageHeader variant")] UnsupportedPageHeaderVariant, - #[fail(display = "UTF8 error: {:?}", _0)] - Utf8Error(str::Utf8Error), -} - -impl From for MigrateError { - fn from(e: io::Error) -> MigrateError { - MigrateError::IoError(e) - } -} - -impl From for MigrateError { - fn from(e: str::Utf8Error) -> MigrateError { - MigrateError::Utf8Error(e) - } -} - -impl From for MigrateError { - fn from(e: num::TryFromIntError) -> MigrateError { - MigrateError::TryFromIntError(e) - } + #[error("UTF8 error: {0:?}")] + Utf8Error(#[from] str::Utf8Error), } impl From<&str> for MigrateError { @@ -99,9 +81,3 @@ impl From for MigrateError { MigrateError::FromString(e) } } - -impl From for MigrateError { - fn from(e: lmdb::Error) -> MigrateError { - MigrateError::LmdbError(e) - } -} diff --git a/src/error.rs b/src/error.rs index 9b8a4c02..ab5c3d4d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,95 +11,88 @@ use std::{ io, path::PathBuf, - str, sync, thread, thread::ThreadId, }; -use failure::Fail; +use thiserror::Error; pub use crate::backend::SafeModeError; use crate::value::Type; -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum DataError { - #[fail(display = "unknown type tag: {}", _0)] + #[error("unknown type tag: {0}")] UnknownType(u8), - #[fail(display = "unexpected type tag: expected {}, got {}", expected, actual)] + #[error("unexpected type tag: expected {expected}, got {actual}")] UnexpectedType { expected: Type, actual: Type, }, - #[fail(display = "empty data; expected tag")] + #[error("empty data; expected tag")] Empty, - #[fail(display = "invalid value for type {}: {}", value_type, err)] + #[error("invalid value for type {value_type}: {err}")] DecodingError { value_type: Type, err: Box, }, - #[fail(display = "couldn't encode value: {}", _0)] - EncodingError(Box), + #[error("couldn't encode value: {0}")] + EncodingError(#[from] Box), - #[fail(display = "invalid uuid bytes")] + #[error("invalid uuid bytes")] InvalidUuid, } -impl From> for DataError { - fn from(e: Box) -> DataError { - DataError::EncodingError(e) - } -} - -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum StoreError { - #[fail(display = "manager poisoned")] + #[error("manager poisoned")] ManagerPoisonError, - #[fail(display = "database corrupted")] + #[error("database corrupted")] DatabaseCorrupted, - #[fail(display = "key/value pair not found")] + #[error("key/value pair not found")] KeyValuePairNotFound, - #[fail(display = "unsupported size of key/DB name/data")] + #[error("unsupported size of key/DB name/data")] KeyValuePairBadSize, - #[fail(display = "file is not a valid database")] + #[error("file is not a valid database")] FileInvalid, - #[fail(display = "environment mapsize reached")] + #[error("environment mapsize reached")] MapFull, - #[fail(display = "environment maxdbs reached")] + #[error("environment maxdbs reached")] DbsFull, - #[fail(display = "environment maxreaders reached")] + #[error("environment maxreaders reached")] ReadersFull, - #[fail(display = "I/O error: {:?}", _0)] - IoError(io::Error), + #[error("I/O error: {0:?}")] + IoError(#[from] io::Error), - #[fail(display = "environment path does not exist or not the right type: {:?}", _0)] + #[error("environment path does not exist or not the right type: {0:?}")] UnsuitableEnvironmentPath(PathBuf), - #[fail(display = "data error: {:?}", _0)] - DataError(DataError), + #[error("data error: {0:?}")] + DataError(#[from] DataError), - #[fail(display = "lmdb backend error: {}", _0)] + #[error("lmdb backend error: {0}")] LmdbError(lmdb::Error), - #[fail(display = "safe mode backend error: {}", _0)] + #[error("safe mode backend error: {0}")] SafeModeError(SafeModeError), - #[fail(display = "read transaction already exists in thread {:?}", _0)] + #[error("read transaction already exists in thread {0:?}")] ReadTransactionAlreadyExists(ThreadId), - #[fail(display = "attempted to open DB during transaction in thread {:?}", _0)] + #[error("attempted to open DB during transaction in thread {0:?}")] OpenAttemptedDuringTransaction(ThreadId), } @@ -113,37 +106,25 @@ impl StoreError { } } -impl From for StoreError { - fn from(e: DataError) -> StoreError { - StoreError::DataError(e) - } -} - -impl From for StoreError { - fn from(e: io::Error) -> StoreError { - StoreError::IoError(e) - } -} - impl From> for StoreError { fn from(_: sync::PoisonError) -> StoreError { StoreError::ManagerPoisonError } } -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum CloseError { - #[fail(display = "manager poisoned")] + #[error("manager poisoned")] ManagerPoisonError, - #[fail(display = "close attempted while manager has an environment still open")] + #[error("close attempted while manager has an environment still open")] EnvironmentStillOpen, - #[fail(display = "close attempted while an environment not known to the manager is still open")] + #[error("close attempted while an environment not known to the manager is still open")] UnknownEnvironmentStillOpen, - #[fail(display = "I/O error: {:?}", _0)] - IoError(io::Error), + #[error("I/O error: {0:?}")] + IoError(#[from] io::Error), } impl From> for CloseError { @@ -152,42 +133,24 @@ impl From> for CloseError { } } -impl From for CloseError { - fn from(e: io::Error) -> CloseError { - CloseError::IoError(e) - } -} - -#[derive(Debug, Fail)] +#[derive(Debug, Error)] pub enum MigrateError { - #[fail(display = "store error: {}", _0)] - StoreError(StoreError), + #[error("store error: {0}")] + StoreError(#[from] StoreError), - #[fail(display = "close error: {}", _0)] - CloseError(CloseError), + #[error("close error: {0}")] + CloseError(#[from] CloseError), - #[fail(display = "manager poisoned")] + #[error("manager poisoned")] ManagerPoisonError, - #[fail(display = "source is empty")] + #[error("source is empty")] SourceEmpty, - #[fail(display = "destination is not empty")] + #[error("destination is not empty")] DestinationNotEmpty, } -impl From for MigrateError { - fn from(e: StoreError) -> MigrateError { - MigrateError::StoreError(e) - } -} - -impl From for MigrateError { - fn from(e: CloseError) -> MigrateError { - MigrateError::CloseError(e) - } -} - impl From> for MigrateError { fn from(_: sync::PoisonError) -> MigrateError { MigrateError::ManagerPoisonError