Skip to content

Commit

Permalink
Replace failure with thiserror
Browse files Browse the repository at this point in the history
  • Loading branch information
upsuper authored and ncloudioj committed Jan 12, 2021
1 parent fba6b3e commit 47f63ae
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 135 deletions.
9 changes: 1 addition & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -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"
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 23 additions & 47 deletions src/backend/impl_lmdb/arch_migrator_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<io::Error> for MigrateError {
fn from(e: io::Error) -> MigrateError {
MigrateError::IoError(e)
}
}

impl From<str::Utf8Error> for MigrateError {
fn from(e: str::Utf8Error) -> MigrateError {
MigrateError::Utf8Error(e)
}
}

impl From<num::TryFromIntError> for MigrateError {
fn from(e: num::TryFromIntError) -> MigrateError {
MigrateError::TryFromIntError(e)
}
#[error("UTF8 error: {0:?}")]
Utf8Error(#[from] str::Utf8Error),
}

impl From<&str> for MigrateError {
Expand All @@ -99,9 +81,3 @@ impl From<String> for MigrateError {
MigrateError::FromString(e)
}
}

impl From<lmdb::Error> for MigrateError {
fn from(e: lmdb::Error) -> MigrateError {
MigrateError::LmdbError(e)
}
}
119 changes: 41 additions & 78 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<bincode::ErrorKind>,
},

#[fail(display = "couldn't encode value: {}", _0)]
EncodingError(Box<bincode::ErrorKind>),
#[error("couldn't encode value: {0}")]
EncodingError(#[from] Box<bincode::ErrorKind>),

#[fail(display = "invalid uuid bytes")]
#[error("invalid uuid bytes")]
InvalidUuid,
}

impl From<Box<bincode::ErrorKind>> for DataError {
fn from(e: Box<bincode::ErrorKind>) -> 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),
}

Expand All @@ -113,37 +106,25 @@ impl StoreError {
}
}

impl From<DataError> for StoreError {
fn from(e: DataError) -> StoreError {
StoreError::DataError(e)
}
}

impl From<io::Error> for StoreError {
fn from(e: io::Error) -> StoreError {
StoreError::IoError(e)
}
}

impl<T> From<sync::PoisonError<T>> for StoreError {
fn from(_: sync::PoisonError<T>) -> 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<T> From<sync::PoisonError<T>> for CloseError {
Expand All @@ -152,42 +133,24 @@ impl<T> From<sync::PoisonError<T>> for CloseError {
}
}

impl From<io::Error> 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<StoreError> for MigrateError {
fn from(e: StoreError) -> MigrateError {
MigrateError::StoreError(e)
}
}

impl From<CloseError> for MigrateError {
fn from(e: CloseError) -> MigrateError {
MigrateError::CloseError(e)
}
}

impl<T> From<sync::PoisonError<T>> for MigrateError {
fn from(_: sync::PoisonError<T>) -> MigrateError {
MigrateError::ManagerPoisonError
Expand Down

0 comments on commit 47f63ae

Please sign in to comment.