Skip to main content

tauri_plugin_velesdb/
error.rs

1//! Error types for the `VelesDB` Tauri plugin.
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6/// Plugin error type.
7#[derive(Debug, Error)]
8pub enum Error {
9    /// Database error from velesdb-core.
10    #[error("Database error: {0}")]
11    Database(#[from] velesdb_core::Error),
12
13    /// Collection not found.
14    #[error("Collection '{0}' not found")]
15    CollectionNotFound(String),
16
17    /// Invalid configuration.
18    #[error("Invalid configuration: {0}")]
19    InvalidConfig(String),
20
21    /// Serialization error.
22    #[error("Serialization error: {0}")]
23    Serialization(String),
24
25    /// IO error.
26    #[error("IO error: {0}")]
27    Io(#[from] std::io::Error),
28}
29
30/// Serializable error for Tauri commands.
31#[derive(Debug, Serialize, Deserialize)]
32pub struct CommandError {
33    /// Error message.
34    pub message: String,
35    /// Error code for programmatic handling.
36    pub code: String,
37}
38
39impl From<Error> for CommandError {
40    fn from(err: Error) -> Self {
41        let code = match &err {
42            Error::Database(_) => "DATABASE_ERROR",
43            Error::CollectionNotFound(_) => "COLLECTION_NOT_FOUND",
44            Error::InvalidConfig(_) => "INVALID_CONFIG",
45            Error::Serialization(_) => "SERIALIZATION_ERROR",
46            Error::Io(_) => "IO_ERROR",
47        };
48        Self {
49            message: err.to_string(),
50            code: code.to_string(),
51        }
52    }
53}
54
55impl From<serde_json::Error> for Error {
56    fn from(err: serde_json::Error) -> Self {
57        Self::Serialization(err.to_string())
58    }
59}
60
61/// Result type alias for plugin operations.
62pub type Result<T> = std::result::Result<T, Error>;
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_error_display_collection_not_found() {
70        // Arrange
71        let err = Error::CollectionNotFound("test_collection".to_string());
72
73        // Act
74        let message = err.to_string();
75
76        // Assert
77        assert_eq!(message, "Collection 'test_collection' not found");
78    }
79
80    #[test]
81    fn test_error_display_invalid_config() {
82        // Arrange
83        let err = Error::InvalidConfig("missing dimension".to_string());
84
85        // Act
86        let message = err.to_string();
87
88        // Assert
89        assert_eq!(message, "Invalid configuration: missing dimension");
90    }
91
92    #[test]
93    fn test_command_error_from_error() {
94        // Arrange
95        let err = Error::CollectionNotFound("docs".to_string());
96
97        // Act
98        let cmd_err: CommandError = err.into();
99
100        // Assert
101        assert_eq!(cmd_err.code, "COLLECTION_NOT_FOUND");
102        assert!(cmd_err.message.contains("docs"));
103    }
104
105    #[test]
106    fn test_command_error_codes() {
107        // Arrange & Act & Assert
108        let cases = vec![
109            (
110                Error::CollectionNotFound("x".to_string()),
111                "COLLECTION_NOT_FOUND",
112            ),
113            (Error::InvalidConfig("x".to_string()), "INVALID_CONFIG"),
114            (Error::Serialization("x".to_string()), "SERIALIZATION_ERROR"),
115        ];
116
117        for (err, expected_code) in cases {
118            let cmd_err: CommandError = err.into();
119            assert_eq!(cmd_err.code, expected_code);
120        }
121    }
122}