1use std::fmt;
6
7#[derive(Debug)]
9pub enum SqliteError {
10 OpenFailed(String),
12
13 DatabaseClosed,
15
16 MigrationFailed(String),
18
19 QueryFailed(String),
21
22 TransactionFailed(String),
24
25 TypeConversion(String),
27
28 InvalidParameter(String),
30
31 TableNotFound(String),
33
34 ConstraintViolation(String),
36
37 IoError(String),
39
40 SerdeError(String),
42
43 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 if e.extended_code == 2067 || e.extended_code == 1555 {
88 Self::ConstraintViolation(detail.to_string())
90 } else if e.extended_code == 787 {
91 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}