Skip to main content

wasm_dbms_api/
error.rs

1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4/// DBMS error type.
5#[derive(Debug, Error, Serialize, Deserialize)]
6#[cfg_attr(feature = "candid", derive(candid::CandidType))]
7pub enum DbmsError {
8    #[error("Access denied: {required:?} (table: {table:?})")]
9    AccessDenied {
10        /// The fingerprint of the table the operation targeted, when
11        /// applicable. `None` for operational perms (`admin`,
12        /// `manage_acl`, `migrate`).
13        table: Option<crate::dbms::table::TableFingerprint>,
14        /// The perm that was missing.
15        required: crate::dbms::acl::RequiredPerm,
16    },
17    #[error("Memory error: {0}")]
18    Memory(#[from] crate::memory::MemoryError),
19    #[error("Migration error: {0}")]
20    Migration(#[from] crate::dbms::migration::MigrationError),
21    #[error("Query error: {0}")]
22    Query(#[from] crate::dbms::query::QueryError),
23    #[error("Sanitize error: {0}")]
24    Sanitize(String),
25    #[error("Table error: {0}")]
26    Table(#[from] crate::dbms::table::TableError),
27    #[error("Transaction error: {0}")]
28    Transaction(#[from] crate::dbms::transaction::TransactionError),
29    #[error("Validation error: {0}")]
30    Validation(String),
31}
32
33/// DBMS result type.
34pub type DbmsResult<T> = Result<T, DbmsError>;
35
36#[cfg(test)]
37mod test {
38
39    use super::*;
40    use crate::dbms::query::QueryError;
41    use crate::dbms::table::TableError;
42    use crate::dbms::transaction::TransactionError;
43    use crate::memory::MemoryError;
44
45    #[test]
46    fn test_should_display_memory_error() {
47        let error = DbmsError::Memory(MemoryError::OutOfBounds);
48        assert_eq!(
49            error.to_string(),
50            "Memory error: Stable memory access out of bounds"
51        );
52    }
53
54    #[test]
55    fn test_should_display_query_error() {
56        let error = DbmsError::Query(QueryError::UnknownColumn("foo".to_string()));
57        assert_eq!(error.to_string(), "Query error: Unknown column: foo");
58    }
59
60    #[test]
61    fn test_should_display_sanitize_error() {
62        let error = DbmsError::Sanitize("invalid input".to_string());
63        assert_eq!(error.to_string(), "Sanitize error: invalid input");
64    }
65
66    #[test]
67    fn test_should_display_table_error() {
68        let error = DbmsError::Table(TableError::TableNotFound);
69        assert_eq!(error.to_string(), "Table error: Table not found");
70    }
71
72    #[test]
73    fn test_should_display_transaction_error() {
74        let error = DbmsError::Transaction(TransactionError::NoActiveTransaction);
75        assert_eq!(
76            error.to_string(),
77            "Transaction error: No active transaction"
78        );
79    }
80
81    #[test]
82    fn test_should_display_validation_error() {
83        let error = DbmsError::Validation("invalid email".to_string());
84        assert_eq!(error.to_string(), "Validation error: invalid email");
85    }
86
87    #[test]
88    fn test_should_convert_from_memory_error() {
89        let error: DbmsError = MemoryError::OutOfBounds.into();
90        assert!(matches!(error, DbmsError::Memory(MemoryError::OutOfBounds)));
91    }
92
93    #[test]
94    fn test_should_convert_from_query_error() {
95        let error: DbmsError = QueryError::UnknownColumn("col".to_string()).into();
96        assert!(matches!(error, DbmsError::Query(_)));
97    }
98
99    #[test]
100    fn test_should_convert_from_table_error() {
101        let error: DbmsError = TableError::TableNotFound.into();
102        assert!(matches!(error, DbmsError::Table(_)));
103    }
104
105    #[test]
106    fn test_should_convert_from_transaction_error() {
107        let error: DbmsError = TransactionError::NoActiveTransaction.into();
108        assert!(matches!(error, DbmsError::Transaction(_)));
109    }
110}