use thiserror::Error;
#[derive(Error, Debug)]
pub enum QuickDbError {
#[error("数据库连接失败: {message}")]
ConnectionError { message: String },
#[error("连接池操作失败: {message}")]
PoolError { message: String },
#[error("查询执行失败: {message}")]
QueryError { message: String },
#[error("数据序列化失败: {message}")]
SerializationError { message: String },
#[error("模型验证失败: {field} - {message}")]
ValidationError { field: String, message: String },
#[error("配置错误: {message}")]
ConfigError { message: String },
#[error("数据库别名 '{alias}' 未找到")]
AliasNotFound { alias: String },
#[error("不支持的数据库类型: {db_type}")]
UnsupportedDatabase { db_type: String },
#[error("事务操作失败: {message}")]
TransactionError { message: String },
#[error("任务执行失败: {0}")]
TaskExecutionError(String),
#[error("缓存操作失败: {message}")]
CacheError { message: String },
#[error("IO 操作失败: {0}")]
IoError(#[from] std::io::Error),
#[error("JSON 处理失败: {0}")]
JsonError(#[from] serde_json::Error),
#[error("操作失败: {0}")]
Other(#[from] anyhow::Error),
#[error("表或集合 '{table}' 不存在: {message}")]
TableNotExistError { table: String, message: String },
}
pub type QuickDbResult<T> = Result<T, QuickDbError>;
pub struct ErrorBuilder;
impl ErrorBuilder {
pub fn connection_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::ConnectionError {
message: message.into(),
}
}
pub fn pool_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::PoolError {
message: message.into(),
}
}
pub fn query_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::QueryError {
message: message.into(),
}
}
pub fn serialization_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::SerializationError {
message: message.into(),
}
}
pub fn validation_error(field: impl Into<String>, message: impl Into<String>) -> QuickDbError {
QuickDbError::ValidationError {
field: field.into(),
message: message.into(),
}
}
pub fn config_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::ConfigError {
message: message.into(),
}
}
pub fn alias_not_found(alias: impl Into<String>) -> QuickDbError {
QuickDbError::AliasNotFound {
alias: alias.into(),
}
}
pub fn unsupported_database(db_type: impl Into<String>) -> QuickDbError {
QuickDbError::UnsupportedDatabase {
db_type: db_type.into(),
}
}
pub fn cache_error(message: impl Into<String>) -> QuickDbError {
QuickDbError::CacheError {
message: message.into(),
}
}
pub fn table_not_exist_error(table: impl Into<String>, message: impl Into<String>) -> QuickDbError {
QuickDbError::TableNotExistError {
table: table.into(),
message: message.into(),
}
}
}
#[macro_export]
macro_rules! quick_error {
(connection, $msg:expr) => {
$crate::error::ErrorBuilder::connection_error($msg)
};
(pool, $msg:expr) => {
$crate::error::ErrorBuilder::pool_error($msg)
};
(query, $msg:expr) => {
$crate::error::ErrorBuilder::query_error($msg)
};
(serialization, $msg:expr) => {
$crate::error::ErrorBuilder::serialization_error($msg)
};
(validation, $field:expr, $msg:expr) => {
$crate::error::ErrorBuilder::validation_error($field, $msg)
};
(config, $msg:expr) => {
$crate::error::ErrorBuilder::config_error($msg)
};
(alias_not_found, $alias:expr) => {
$crate::error::ErrorBuilder::alias_not_found($alias)
};
(unsupported_db, $db_type:expr) => {
$crate::error::ErrorBuilder::unsupported_database($db_type)
};
(cache, $msg:expr) => {
$crate::error::ErrorBuilder::cache_error($msg)
};
(table_not_exist, $table:expr, $msg:expr) => {
$crate::error::ErrorBuilder::table_not_exist_error($table, $msg)
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let err = ErrorBuilder::connection_error("测试连接失败");
assert!(matches!(err, QuickDbError::ConnectionError { .. }));
assert_eq!(err.to_string(), "数据库连接失败: 测试连接失败");
}
#[test]
fn test_error_macro() {
let err = quick_error!(validation, "用户名", "不能为空");
assert!(matches!(err, QuickDbError::ValidationError { .. }));
assert_eq!(err.to_string(), "模型验证失败: 用户名 - 不能为空");
}
#[test]
fn test_table_not_exist_error() {
let err = ErrorBuilder::table_not_exist_error("users", "表不存在");
assert!(matches!(err, QuickDbError::TableNotExistError { .. }));
assert_eq!(err.to_string(), "表或集合 'users' 不存在: 表不存在");
}
#[test]
fn test_table_not_exist_macro() {
let err = quick_error!(table_not_exist, "products", "产品表不存在");
assert!(matches!(err, QuickDbError::TableNotExistError { .. }));
assert_eq!(err.to_string(), "表或集合 'products' 不存在: 产品表不存在");
}
}