1use miette::Diagnostic;
4use thiserror::Error;
5
6#[derive(Error, Diagnostic, Debug)]
8pub enum DbError {
9 #[error("Database connection failed: {0}")]
10 #[diagnostic(
11 code(soar_db::connection),
12 help("Check if the database file exists and is accessible")
13 )]
14 ConnectionError(String),
15
16 #[error("Database query failed: {0}")]
17 #[diagnostic(
18 code(soar_db::query),
19 help("Try running 'soar sync' to refresh the database")
20 )]
21 QueryError(String),
22
23 #[error("Database migration failed: {0}")]
24 #[diagnostic(
25 code(soar_db::migration),
26 help("The database schema may be corrupted. Try removing and re-syncing.")
27 )]
28 MigrationError(String),
29
30 #[error("Package not found: {0}")]
31 #[diagnostic(
32 code(soar_db::not_found),
33 help("Run 'soar sync' to update package list, or check the package name")
34 )]
35 NotFound(String),
36
37 #[error("Package already installed: {0}")]
38 #[diagnostic(
39 code(soar_db::already_installed),
40 help("Use 'soar update' to update the package, or 'soar remove' first")
41 )]
42 AlreadyInstalled(String),
43
44 #[error("Database integrity error: {0}")]
45 #[diagnostic(
46 code(soar_db::integrity),
47 help("The database may be corrupted. Try removing and re-syncing.")
48 )]
49 IntegrityError(String),
50
51 #[error(transparent)]
52 #[diagnostic(code(soar_db::io), help("Check file permissions and disk space"))]
53 IoError(#[from] std::io::Error),
54}
55
56impl From<diesel::result::Error> for DbError {
57 fn from(err: diesel::result::Error) -> Self {
58 match err {
59 diesel::result::Error::NotFound => DbError::NotFound("Record not found".to_string()),
60 diesel::result::Error::DatabaseError(_, info) => {
61 DbError::QueryError(info.message().to_string())
62 }
63 other => DbError::QueryError(other.to_string()),
64 }
65 }
66}
67
68impl From<diesel::result::ConnectionError> for DbError {
69 fn from(err: diesel::result::ConnectionError) -> Self {
70 DbError::ConnectionError(err.to_string())
71 }
72}
73
74pub type Result<T> = std::result::Result<T, DbError>;