Skip to main content

dm_database_sqllog2db/
error.rs

1use std::io;
2use std::path::PathBuf;
3use thiserror::Error;
4
5/// 应用程序错误类型
6#[derive(Debug, Error)]
7pub enum Error {
8    /// Configuration related error
9    #[error("Configuration error: {0}")]
10    Config(#[from] ConfigError),
11
12    /// File operation error
13    #[error("File error: {0}")]
14    File(#[from] FileError),
15
16    /// Database operation error
17    #[error("Database error: {0}")]
18    Database(#[from] DatabaseError),
19
20    /// Parse error
21    #[error("Parse error: {0}")]
22    Parse(#[from] ParseError),
23
24    /// SQL log parser error
25    #[error("SQL log parser error: {0}")]
26    Parser(#[from] ParserError),
27
28    /// Export error
29    #[error("Export error: {0}")]
30    Export(#[from] ExportError),
31
32    /// Update error
33    #[error("Update error: {0}")]
34    Update(#[from] UpdateError),
35
36    /// IO error
37    #[error("IO error: {0}")]
38    Io(#[from] io::Error),
39}
40
41/// 更新错误
42#[derive(Debug, Error)]
43pub enum UpdateError {
44    /// Update failed
45    #[error("Update failed: {0}")]
46    UpdateFailed(String),
47
48    /// Check for updates failed
49    #[error("Check for updates failed: {0}")]
50    CheckFailed(String),
51}
52
53/// 配置错误
54#[derive(Debug, Error)]
55pub enum ConfigError {
56    /// Configuration file not found
57    #[error("Configuration file not found: {0}")]
58    NotFound(PathBuf),
59
60    /// Configuration file parse failed
61    #[error("Failed to parse configuration file {path}: {reason}")]
62    ParseFailed { path: PathBuf, reason: String },
63
64    /// Invalid log level
65    #[error("Invalid log level '{level}', valid values: {}", valid_levels.join(", "))]
66    InvalidLogLevel {
67        level: String,
68        valid_levels: Vec<String>,
69    },
70
71    /// Invalid configuration value
72    #[error("Invalid configuration value {field} = '{value}': {reason}")]
73    InvalidValue {
74        field: String,
75        value: String,
76        reason: String,
77    },
78
79    /// Missing required configuration: no exporters configured
80    #[error("At least one exporter must be configured (database/csv)")]
81    NoExporters,
82}
83
84/// 文件操作错误
85#[derive(Debug, Error)]
86pub enum FileError {
87    /// File already exists
88    #[error("File already exists: {path} (set overwrite=true to replace)")]
89    AlreadyExists { path: PathBuf },
90
91    /// File write failed
92    #[error("Failed to write file {path}: {reason}")]
93    WriteFailed { path: PathBuf, reason: String },
94
95    /// Create directory failed
96    #[error("Failed to create directory {path}: {reason}")]
97    CreateDirectoryFailed { path: PathBuf, reason: String },
98}
99
100/// 数据库错误
101#[derive(Debug, Error)]
102pub enum DatabaseError {}
103
104/// 解析错误
105#[derive(Debug, Error)]
106pub enum ParseError {}
107
108/// SQL 日志解析器错误
109#[derive(Debug, Error)]
110pub enum ParserError {
111    /// Path not found
112    #[error("Path not found: {path}")]
113    PathNotFound { path: PathBuf },
114
115    /// Invalid path
116    #[error("Invalid path {path}: {reason}")]
117    InvalidPath { path: PathBuf, reason: String },
118
119    /// Read directory failed
120    #[error("Failed to read directory {path}: {reason}")]
121    ReadDirFailed { path: PathBuf, reason: String },
122}
123
124/// 导出错误
125/// 所有变体都以 `...Failed` 结尾,以清楚表示各种导出失败情形
126#[derive(Debug, Error)]
127#[allow(clippy::enum_variant_names)]
128pub enum ExportError {
129    /// CSV export failed
130    #[error("CSV export failed {path}: {reason}")]
131    CsvExportFailed { path: PathBuf, reason: String },
132    /// Failed to create output file
133    #[error("Failed to create output file {path}: {reason}")]
134    FileCreateFailed { path: PathBuf, reason: String },
135
136    /// Failed to write file
137    #[error("Failed to write file {path}: {reason}")]
138    FileWriteFailed { path: PathBuf, reason: String },
139
140    /// Database operation error
141    #[cfg(feature = "sqlite")]
142    #[error("Database error: {reason}")]
143    DatabaseError { reason: String },
144}
145
146/// 应用程序 Result 类型别名
147pub type Result<T> = std::result::Result<T, Error>;
148
149// 辅助宏,用于快速创建错误
150#[macro_export]
151macro_rules! config_error {
152    ($variant:ident { $($field:ident: $value:expr),+ $(,)? }) => {
153        $crate::error::Error::Config($crate::error::ConfigError::$variant {
154            $($field: $value),+
155        })
156    };
157}
158
159#[macro_export]
160macro_rules! file_error {
161    ($variant:ident { $($field:ident: $value:expr),+ $(,)? }) => {
162        $crate::error::Error::File($crate::error::FileError::$variant {
163            $($field: $value),+
164        })
165    };
166}
167
168#[macro_export]
169macro_rules! database_error {
170    ($variant:ident { $($field:ident: $value:expr),+ $(,)? }) => {
171        $crate::error::Error::Database($crate::error::DatabaseError::$variant {
172            $($field: $value),+
173        })
174    };
175}
176
177#[macro_export]
178macro_rules! parse_error {
179    ($variant:ident { $($field:ident: $value:expr),+ $(,)? }) => {
180        $crate::error::Error::Parse($crate::error::ParseError::$variant {
181            $($field: $value),+
182        })
183    };
184}
185
186#[macro_export]
187macro_rules! export_error {
188    ($variant:ident { $($field:ident: $value:expr),+ $(,)? }) => {
189        $crate::error::Error::Export($crate::error::ExportError::$variant {
190            $($field: $value),+
191        })
192    };
193}