Revision control
Copy as Markdown
Other Tools
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use std::{io, path::PathBuf, sync, thread, thread::ThreadId};
use thiserror::Error;
pub use crate::backend::SafeModeError;
use crate::value::Type;
#[derive(Debug, Error)]
pub enum DataError {
#[error("unknown type tag: {0}")]
UnknownType(u8),
#[error("unexpected type tag: expected {expected}, got {actual}")]
UnexpectedType { expected: Type, actual: Type },
#[error("empty data; expected tag")]
Empty,
#[error("invalid value for type {value_type}: {err}")]
DecodingError {
value_type: Type,
err: Box<bincode::ErrorKind>,
},
#[error("couldn't encode value: {0}")]
EncodingError(#[from] Box<bincode::ErrorKind>),
#[error("invalid uuid bytes")]
InvalidUuid,
}
#[derive(Debug, Error)]
pub enum StoreError {
#[error("manager poisoned")]
ManagerPoisonError,
#[error("database corrupted")]
DatabaseCorrupted,
#[error("key/value pair not found")]
KeyValuePairNotFound,
#[error("unsupported size of key/DB name/data")]
KeyValuePairBadSize,
#[error("file is not a valid database")]
FileInvalid,
#[error("environment mapsize reached")]
MapFull,
#[error("environment maxdbs reached")]
DbsFull,
#[error("environment maxreaders reached")]
ReadersFull,
#[error("I/O error: {0:?}")]
IoError(#[from] io::Error),
#[error("environment path does not exist or not the right type: {0:?}")]
UnsuitableEnvironmentPath(PathBuf),
#[error("data error: {0:?}")]
DataError(#[from] DataError),
#[cfg(feature = "lmdb")]
#[error("lmdb backend error: {0}")]
LmdbError(lmdb::Error),
#[error("safe mode backend error: {0}")]
SafeModeError(SafeModeError),
#[error("read transaction already exists in thread {0:?}")]
ReadTransactionAlreadyExists(ThreadId),
#[error("attempted to open DB during transaction in thread {0:?}")]
OpenAttemptedDuringTransaction(ThreadId),
}
impl StoreError {
pub fn open_during_transaction() -> StoreError {
StoreError::OpenAttemptedDuringTransaction(thread::current().id())
}
pub fn read_transaction_already_exists() -> StoreError {
StoreError::ReadTransactionAlreadyExists(thread::current().id())
}
}
impl<T> From<sync::PoisonError<T>> for StoreError {
fn from(_: sync::PoisonError<T>) -> StoreError {
StoreError::ManagerPoisonError
}
}
#[derive(Debug, Error)]
pub enum CloseError {
#[error("manager poisoned")]
ManagerPoisonError,
#[error("close attempted while manager has an environment still open")]
EnvironmentStillOpen,
#[error("close attempted while an environment not known to the manager is still open")]
UnknownEnvironmentStillOpen,
#[error("I/O error: {0:?}")]
IoError(#[from] io::Error),
}
impl<T> From<sync::PoisonError<T>> for CloseError {
fn from(_: sync::PoisonError<T>) -> CloseError {
CloseError::ManagerPoisonError
}
}
#[derive(Debug, Error)]
pub enum MigrateError {
#[error("store error: {0}")]
StoreError(#[from] StoreError),
#[error("close error: {0}")]
CloseError(#[from] CloseError),
#[error("manager poisoned")]
ManagerPoisonError,
#[error("source is empty")]
SourceEmpty,
#[error("destination is not empty")]
DestinationNotEmpty,
}
impl<T> From<sync::PoisonError<T>> for MigrateError {
fn from(_: sync::PoisonError<T>) -> MigrateError {
MigrateError::ManagerPoisonError
}
}