Skip to main content

tauri_plugin_persistence/api/
error.rs

1use serde::{Deserialize, Serialize};
2use specta::Type;
3
4#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error, Type)]
5#[serde(rename_all = "snake_case", tag = "kind")]
6pub enum Error {
7    #[error("An unexpected error occurred: {reason}")]
8    Unknown{ reason: String },
9
10    #[error("Failed to open context {name} at {path}: {reason}")]
11    OpenContext {
12        name: String,
13        path: String,
14        reason: String
15    },
16
17    #[error("Failed to open database {name} in context {context} at {path}: {reason}")]
18    OpenDatabase {
19        name: String,
20        context: String,
21        path: String,
22        reason: String
23    },
24
25    #[error("Failed to open {path} in {context}: {reason}")]
26    OpenFileHandle {
27        path: String,
28        context: String,
29        reason: String
30    },
31
32    #[error("The requested context ({reason}) has not been initialized.")]
33    UnknownContext{ reason: String },
34
35    #[error("The requested database ({reason}) has not been opened.")]
36    UnknownDatabase{ reason: String },
37
38    #[error("The file handle with ID {reason} does not exist.")]
39    UnknownFileHandle{ reason: String },
40
41    #[error("Unknown transaction ID {reason} in current database.")]
42    UnknownTransaction{ reason: String },
43
44    #[error("Invalid path: {reason}")]
45    InvalidPath{ reason: String },
46
47    #[error("Cannot use an absolute path in this context: {reason}")]
48    NoAbsolutePaths{ reason: String },
49
50    #[error("Specified relative path escapes root path of this context: {reason}")]
51    PathEscapesContext{ reason: String },
52
53    #[error("Encountered a database error: {reason}")]
54    DatabaseError{ reason: String },
55
56    #[error("Serialization error: {reason}")]
57    SerializationError{ reason: String },
58
59    #[error("Deserialization error: {reason}")]
60    DeserializationError{ reason: String },
61
62    #[error("Encountered an IO error: {reason}")]
63    IOError{ reason: String },
64
65    #[error("Failed to encode {reason} bytes as UTF-8 string.")]
66    StringEncodingError{ reason: String },
67
68    #[error("Filesystem operation failed ({operation}): {reason}")]
69    FilesystemError {operation: String, reason: String}
70}
71
72impl From<anyhow::Error> for Error {
73    fn from(value: anyhow::Error) -> Self {
74        Self::Unknown{reason: value.to_string()}
75    }
76}
77
78impl From<polodb_core::Error> for Error {
79    fn from(value: polodb_core::Error) -> Self {
80        Self::DatabaseError{reason: value.to_string()}
81    }
82}
83
84impl From<bson::ser::Error> for Error {
85    fn from(value: bson::ser::Error) -> Self {
86        Self::SerializationError{reason: value.to_string()}
87    }
88}
89
90impl From<bson::de::Error> for Error {
91    fn from(value: bson::de::Error) -> Self {
92        Self::DeserializationError{reason: value.to_string()}
93    }
94}
95
96impl From<std::io::Error> for Error {
97    fn from(value: std::io::Error) -> Self {
98        Self::IOError {reason: value.to_string()}
99    }
100}
101
102impl Error {
103    pub fn open_context(name: impl AsRef<str>, path: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
104        Self::OpenContext { name: name.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
105    }
106
107    pub fn invalid_path(path: impl AsRef<str>) -> Self {
108        Self::InvalidPath{reason: path.as_ref().to_string()}
109    }
110
111    pub fn unknown_context(name: impl AsRef<str>) -> Self {
112        Self::UnknownContext{reason: name.as_ref().to_string()}
113    }
114
115    pub fn open_database(name: impl AsRef<str>, context: impl AsRef<str>, path: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
116        Self::OpenDatabase { name: name.as_ref().to_string(), context: context.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
117    }
118
119    pub fn unknown_database(name: impl AsRef<str>) -> Self {
120        Self::UnknownDatabase{reason: name.as_ref().to_string()}
121    }
122
123    pub fn no_absolute_path(path: impl AsRef<str>) -> Self {
124        Self::NoAbsolutePaths{reason: path.as_ref().to_string()}
125    }
126
127    pub fn path_escapes_context(path: impl AsRef<str>) -> Self {
128        Self::PathEscapesContext{reason: path.as_ref().to_string()}
129    }
130
131    pub fn open_file_handle(path: impl AsRef<str>, context: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
132        Self::OpenFileHandle { context: context.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
133    }
134
135    pub fn unknown_file_handle(id: impl AsRef<str>) -> Self {
136        Self::UnknownFileHandle{reason: id.as_ref().to_string()}
137    }
138
139    pub fn unknown_transaction(id: impl AsRef<str>) -> Self {
140        Self::UnknownTransaction{reason: id.as_ref().to_string()}
141    }
142
143    pub fn string_encoding(size: usize) -> Self {
144        Self::StringEncodingError{reason: size.to_string()}
145    }
146
147    pub fn filesystem(operation: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
148        Self::FilesystemError { operation: operation.as_ref().to_string(), reason: reason.as_ref().to_string() }
149    }
150}
151
152pub type Result<T> = std::result::Result<T, Error>;