Replace failure with thiserror

without.crypto
Xidorn Quan 3 years ago committed by Nan Jiang
parent fba6b3eb06
commit 47f63aead1
  1. 9
      Cargo.toml
  2. 2
      README.md
  3. 70
      src/backend/impl_lmdb/arch_migrator_error.rs
  4. 119
      src/error.rs

@ -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"

@ -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

@ -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 {
@ -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)
}
}

@ -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),
}
@ -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 {
@ -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

Loading…
Cancel
Save