use thiserror::Error; /// Errors that can occur during command processing. #[derive(Debug, Error)] pub enum CommandError { #[error("command not implemented: {0}")] NotImplemented(String), #[error("invalid argument: {0}")] InvalidArgument(String), #[error("storage error: {0}")] StorageError(String), #[error("index error: {0}")] IndexError(String), #[error("transaction error: {0}")] TransactionError(String), #[error("no such transaction: {0}")] NoSuchTransaction(String), #[error("write conflict: {0}")] WriteConflict(String), #[error("namespace not found: {0}")] NamespaceNotFound(String), #[error("namespace already exists: {0}")] NamespaceExists(String), #[error("duplicate key: {0}")] DuplicateKey(String), #[error("immutable field: {0}")] ImmutableField(String), #[error("unauthorized: {0}")] Unauthorized(String), #[error("authentication failed")] AuthenticationFailed, #[error("illegal operation: {0}")] IllegalOperation(String), #[error("internal error: {0}")] InternalError(String), } impl CommandError { /// Convert a CommandError to a BSON error response document. pub fn to_error_doc(&self) -> bson::Document { let (code, code_name) = match self { CommandError::NotImplemented(_) => (59, "CommandNotFound"), CommandError::InvalidArgument(_) => (14, "TypeMismatch"), CommandError::StorageError(_) => (1, "InternalError"), CommandError::IndexError(_) => (27, "IndexNotFound"), CommandError::TransactionError(_) => (112, "WriteConflict"), CommandError::NoSuchTransaction(_) => (251, "NoSuchTransaction"), CommandError::WriteConflict(_) => (112, "WriteConflict"), CommandError::NamespaceNotFound(_) => (26, "NamespaceNotFound"), CommandError::NamespaceExists(_) => (48, "NamespaceExists"), CommandError::DuplicateKey(_) => (11000, "DuplicateKey"), CommandError::ImmutableField(_) => (66, "ImmutableField"), CommandError::Unauthorized(_) => (13, "Unauthorized"), CommandError::AuthenticationFailed => (18, "AuthenticationFailed"), CommandError::IllegalOperation(_) => (20, "IllegalOperation"), CommandError::InternalError(_) => (1, "InternalError"), }; bson::doc! { "ok": 0, "errmsg": self.to_string(), "code": code, "codeName": code_name, } } } impl From for CommandError { fn from(e: rustdb_storage::StorageError) -> Self { CommandError::StorageError(e.to_string()) } } impl From for CommandError { fn from(e: rustdb_txn::TransactionError) -> Self { match e { rustdb_txn::TransactionError::NotFound(message) => { CommandError::NoSuchTransaction(message) } rustdb_txn::TransactionError::WriteConflict(message) => { CommandError::WriteConflict(message) } other => CommandError::TransactionError(other.to_string()), } } } impl From for CommandError { fn from(e: rustdb_index::IndexError) -> Self { CommandError::IndexError(e.to_string()) } } pub type CommandResult = Result;