unistore_sqlite/
error.rs

1//! SQLite 错误类型
2//!
3//! 职责:定义 SQLite 操作的所有错误类型
4
5use std::fmt;
6
7/// SQLite 操作错误
8#[derive(Debug)]
9pub enum SqliteError {
10    /// 数据库打开失败
11    OpenFailed(String),
12
13    /// 数据库已关闭
14    DatabaseClosed,
15
16    /// 迁移失败
17    MigrationFailed(String),
18
19    /// 查询执行失败
20    QueryFailed(String),
21
22    /// 事务失败
23    TransactionFailed(String),
24
25    /// 类型转换失败
26    TypeConversion(String),
27
28    /// 参数错误
29    InvalidParameter(String),
30
31    /// 表不存在
32    TableNotFound(String),
33
34    /// 约束违反(唯一、外键等)
35    ConstraintViolation(String),
36
37    /// IO 错误
38    IoError(String),
39
40    /// 序列化/反序列化错误
41    SerdeError(String),
42
43    /// 内部错误
44    Internal(String),
45}
46
47impl fmt::Display for SqliteError {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        match self {
50            Self::OpenFailed(msg) => write!(f, "数据库打开失败: {}", msg),
51            Self::DatabaseClosed => write!(f, "数据库已关闭"),
52            Self::MigrationFailed(msg) => write!(f, "迁移失败: {}", msg),
53            Self::QueryFailed(msg) => write!(f, "查询失败: {}", msg),
54            Self::TransactionFailed(msg) => write!(f, "事务失败: {}", msg),
55            Self::TypeConversion(msg) => write!(f, "类型转换失败: {}", msg),
56            Self::InvalidParameter(msg) => write!(f, "参数错误: {}", msg),
57            Self::TableNotFound(table) => write!(f, "表不存在: {}", table),
58            Self::ConstraintViolation(msg) => write!(f, "约束违反: {}", msg),
59            Self::IoError(msg) => write!(f, "IO 错误: {}", msg),
60            Self::SerdeError(msg) => write!(f, "序列化错误: {}", msg),
61            Self::Internal(msg) => write!(f, "内部错误: {}", msg),
62        }
63    }
64}
65
66impl std::error::Error for SqliteError {}
67
68impl From<std::io::Error> for SqliteError {
69    fn from(err: std::io::Error) -> Self {
70        Self::IoError(err.to_string())
71    }
72}
73
74impl From<serde_json::Error> for SqliteError {
75    fn from(err: serde_json::Error) -> Self {
76        Self::SerdeError(err.to_string())
77    }
78}
79
80impl From<rusqlite::Error> for SqliteError {
81    fn from(err: rusqlite::Error) -> Self {
82        use rusqlite::Error;
83        match &err {
84            Error::SqliteFailure(e, msg) => {
85                let detail = msg.as_deref().unwrap_or("unknown");
86                // 检查约束违反
87                if e.extended_code == 2067 || e.extended_code == 1555 {
88                    // UNIQUE constraint
89                    Self::ConstraintViolation(detail.to_string())
90                } else if e.extended_code == 787 {
91                    // FOREIGN KEY constraint
92                    Self::ConstraintViolation(format!("外键约束: {}", detail))
93                } else {
94                    Self::QueryFailed(format!("{:?}: {}", e.code, detail))
95                }
96            }
97            Error::QueryReturnedNoRows => Self::QueryFailed("查询无结果".to_string()),
98            Error::InvalidColumnType(idx, name, _) => {
99                Self::TypeConversion(format!("列 {}({}) 类型不匹配", name, idx))
100            }
101            _ => Self::QueryFailed(err.to_string()),
102        }
103    }
104}
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109
110    #[test]
111    fn test_error_display() {
112        let err = SqliteError::OpenFailed("permission denied".into());
113        assert!(err.to_string().contains("数据库打开失败"));
114
115        let err = SqliteError::TableNotFound("users".into());
116        assert!(err.to_string().contains("users"));
117    }
118
119    #[test]
120    fn test_io_error_conversion() {
121        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
122        let sqlite_err: SqliteError = io_err.into();
123        assert!(matches!(sqlite_err, SqliteError::IoError(_)));
124    }
125}