matrix_sdk_sqlite/
error.rs1#[cfg(feature = "event-cache")]
16use std::sync::Arc;
17
18#[cfg(feature = "event-cache")]
19use matrix_sdk_base::event_cache::store::EventCacheStoreError;
20#[cfg(feature = "event-cache")]
21use matrix_sdk_base::media::store::MediaStoreError;
22#[cfg(feature = "state-store")]
23use matrix_sdk_base::store::StoreError as StateStoreError;
24#[cfg(feature = "crypto-store")]
25use matrix_sdk_crypto::CryptoStoreError;
26use thiserror::Error;
27use tokio::io;
28
29use crate::connection::{CreatePoolError, PoolError};
30
31#[derive(Error, Debug)]
33#[non_exhaustive]
34pub enum OpenStoreError {
35 #[error("Failed to create the database's parent directory: {0}")]
37 CreateDir(#[source] io::Error),
38
39 #[error(transparent)]
41 CreatePool(#[from] CreatePoolError),
42
43 #[error("Failed to load database version: {0}")]
45 LoadVersion(#[source] rusqlite::Error),
46
47 #[error("Missing database version")]
49 MissingVersion,
50
51 #[error("Invalid database version")]
53 InvalidVersion,
54
55 #[error("Failed to run migrations: {0}")]
57 Migration(#[from] Error),
58
59 #[error(transparent)]
61 Pool(#[from] PoolError),
62
63 #[error("Failed to initialize the store cipher: {0}")]
65 InitCipher(#[from] matrix_sdk_store_encryption::Error),
66
67 #[error("Failed to load the store cipher from the DB: {0}")]
69 LoadCipher(#[source] rusqlite::Error),
70
71 #[error("Failed to save the store cipher to the DB: {0}")]
73 SaveCipher(#[source] rusqlite::Error),
74}
75
76#[derive(Debug, Error)]
77pub enum Error {
78 #[error(transparent)]
79 Sqlite(rusqlite::Error),
80
81 #[error("Failed to compute the maximum variable number from {0}")]
82 SqliteMaximumVariableNumber(i32),
83
84 #[error(transparent)]
85 Pool(PoolError),
86
87 #[error(transparent)]
88 Encode(rmp_serde::encode::Error),
89
90 #[error(transparent)]
91 Decode(rmp_serde::decode::Error),
92
93 #[error(transparent)]
94 Json(#[from] serde_json::Error),
95
96 #[error(transparent)]
97 Encryption(matrix_sdk_store_encryption::Error),
98
99 #[error("can't save/load sessions or group sessions in the store before an account is stored")]
100 AccountUnset,
101
102 #[error(transparent)]
103 Pickle(#[from] vodozemac::PickleError),
104
105 #[error("An object failed to be decrypted while unpickling")]
106 Unpickle,
107
108 #[error("Redaction failed: {0}")]
109 Redaction(#[source] ruma::canonical_json::RedactionError),
110
111 #[error("An update keyed by unique ID touched more than one entry")]
112 InconsistentUpdate,
113
114 #[error("The store contains invalid data: {details}")]
115 InvalidData { details: String },
116
117 #[error("The store is closed")]
118 StoreClosed,
119}
120
121macro_rules! impl_from {
122 ( $ty:ty => $enum:ident::$variant:ident ) => {
123 impl From<$ty> for $enum {
124 fn from(value: $ty) -> Self {
125 Self::$variant(value)
126 }
127 }
128 };
129}
130
131impl From<rusqlite::Error> for Error {
132 fn from(error: rusqlite::Error) -> Self {
133 if let rusqlite::Error::SqliteFailure(ffi_error, message) = &error
134 && ffi_error.code == rusqlite::ErrorCode::DatabaseBusy
135 {
136 tracing::error!(
138 sentry = true,
139 sqlite_message = message,
140 "observed database busy error"
141 );
142 }
143 Error::Sqlite(error)
144 }
145}
146
147impl_from!(PoolError => Error::Pool);
148impl_from!(rmp_serde::encode::Error => Error::Encode);
149impl_from!(rmp_serde::decode::Error => Error::Decode);
150impl_from!(matrix_sdk_store_encryption::Error => Error::Encryption);
151
152#[cfg(feature = "crypto-store")]
153impl From<Error> for CryptoStoreError {
154 fn from(e: Error) -> Self {
155 CryptoStoreError::backend(e)
156 }
157}
158
159#[cfg(feature = "state-store")]
160impl From<Error> for StateStoreError {
161 fn from(e: Error) -> Self {
162 match e {
163 Error::Json(e) => StateStoreError::Json(e),
164 Error::Encryption(e) => StateStoreError::Encryption(e),
165 Error::Redaction(e) => StateStoreError::Redaction(e),
166 e => StateStoreError::backend(e),
167 }
168 }
169}
170
171#[cfg(feature = "event-cache")]
172impl From<Error> for EventCacheStoreError {
173 fn from(e: Error) -> Self {
174 match e {
175 Error::Encryption(e) => EventCacheStoreError::Encryption(Arc::new(e)),
176 e => EventCacheStoreError::backend(e),
177 }
178 }
179}
180
181#[cfg(feature = "event-cache")]
182impl From<Error> for MediaStoreError {
183 fn from(e: Error) -> Self {
184 match e {
185 Error::Encryption(e) => MediaStoreError::Encryption(e),
186 e => MediaStoreError::backend(e),
187 }
188 }
189}
190
191pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;