use std::{fmt, io, sync::Arc};
use vart::TrieError;
use crate::log::Error as LogError;
use crate::store::Task;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Clone, Debug)]
pub enum Error {
Abort, IoError(Arc<io::Error>), LogError(LogError), EmptyKey, TransactionClosed, NonExpirable, CorruptedMetadata, TransactionReadOnly, IndexError(TrieError), KeyNotFound, CorruptedIndex, TransactionReadConflict, TransactionWriteConflict, StoreClosed, InvalidAttributeData, UnknownAttributeType, CorruptedTransactionRecord(String), CorruptedTransactionHeader(String), InvalidTransactionRecordId, EmptyValue, ManifestNotFound, TransactionWriteOnly, SendError(String),
ReceiveError(String),
RevisionError(String),
MismatchedSegmentID(u64, u64),
CompactionAlreadyInProgress, MergeManifestMissing, CustomError(String), InvalidOperation, CompactionSegmentSizeTooSmall, SegmentIdExceedsLastUpdated, TransactionMustBeReadOnly, TransactionWithoutSavepoint, MaxKVMetadataLengthExceeded, ChecksumMismatch(u32, u32), SnapshotVersionIsOld(u64, u64), }
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Abort => write!(f, "Operation aborted"),
Error::IoError(err) => write!(f, "IO error: {}", err),
Error::EmptyKey => write!(f, "Empty key"),
Error::TransactionClosed => {
write!(f, "This transaction has been closed")
}
Error::NonExpirable => write!(f, "This entry cannot be expired"),
Error::CorruptedMetadata => write!(f, "Corrupted metadata"),
Error::TransactionReadOnly => write!(f, "This transaction is read-only"),
Error::IndexError(trie_error) => write!(f, "Index error: {}", trie_error),
Error::KeyNotFound => write!(f, "Key not found"),
Error::CorruptedIndex => write!(f, "Corrupted index"),
Error::TransactionReadConflict => write!(f, "Transaction read conflict"),
Error::TransactionWriteConflict => write!(f, "Transaction write conflict"),
Error::StoreClosed => write!(f, "Store closed"),
Error::InvalidAttributeData => write!(f, "Invalid attribute data"),
Error::UnknownAttributeType => write!(f, "Unknown attribute type"),
Error::LogError(log_error) => write!(f, "Log error: {}", log_error),
Error::CorruptedTransactionRecord(msg) => {
write!(f, "Corrupted transaction record: {}", msg)
}
Error::CorruptedTransactionHeader(msg) => {
write!(f, "Corrupted transaction header: {}", msg)
}
Error::InvalidTransactionRecordId => write!(f, "Invalid transaction record ID"),
Error::EmptyValue => write!(f, "Empty value in the record"),
Error::ManifestNotFound => write!(f, "Manifest not found"),
Error::TransactionWriteOnly => write!(f, "Transaction is write-only"),
Error::SendError(err) => write!(f, "Send error: {}", err),
Error::ReceiveError(err) => write!(f, "Receive error: {}", err),
Error::MismatchedSegmentID(expected, found) => write!(
f,
"Mismatched segment ID: expected={}, found={}",
expected, found
),
Error::CompactionAlreadyInProgress => write!(f, "Compaction is in progress"),
Error::RevisionError(err) => write!(f, "Revision error: {}", err),
Error::MergeManifestMissing => write!(f, "Merge manifest is missing"),
Error::CustomError(err) => write!(f, "Error: {}", err),
Error::InvalidOperation => write!(f, "Invalid operation"),
Error::CompactionSegmentSizeTooSmall => {
write!(
f,
"Segment size is too small for compaction, must be >= max_segment_size"
)
}
Error::SegmentIdExceedsLastUpdated => {
write!(f, "Segment ID exceeds the last updated segment")
}
Error::TransactionMustBeReadOnly => {
write!(f, "Transaction must be read-only")
}
Error::TransactionWithoutSavepoint => {
write!(f, "Transaction does not have a savepoint set")
}
Error::MaxKVMetadataLengthExceeded => {
write!(f, "Maximum KV metadata length exceeded")
}
Error::ChecksumMismatch(expected, found) => {
write!(
f,
"Checksum mismatch: expected={}, found={}",
expected, found
)
}
Error::SnapshotVersionIsOld(expected, found) => {
write!(
f,
"Snapshot version is old: read_ts={}, index={}",
expected, found
)
}
}
}
}
impl std::error::Error for Error {}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::IoError(Arc::new(e))
}
}
impl From<TrieError> for Error {
fn from(trie_error: TrieError) -> Self {
Error::IndexError(trie_error)
}
}
impl From<LogError> for Error {
fn from(log_error: LogError) -> Self {
Error::LogError(log_error)
}
}
impl From<async_channel::SendError<Task>> for Error {
fn from(error: async_channel::SendError<Task>) -> Self {
Error::SendError(format!("Async channel send error: {}", error))
}
}
impl From<async_channel::SendError<std::result::Result<(), Error>>> for Error {
fn from(error: async_channel::SendError<std::result::Result<(), Error>>) -> Self {
Error::SendError(format!("Async channel send error: {}", error))
}
}
impl From<async_channel::RecvError> for Error {
fn from(error: async_channel::RecvError) -> Self {
Error::ReceiveError(format!("Async channel receive error: {}", error))
}
}
impl From<revision::Error> for Error {
fn from(err: revision::Error) -> Self {
Error::RevisionError(err.to_string())
}
}