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