1// Copyright 2023 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
1415use deadpool_sqlite::{CreatePoolError, PoolError};
16#[cfg(feature = "event-cache")]
17use matrix_sdk_base::event_cache::store::EventCacheStoreError;
18#[cfg(feature = "state-store")]
19use matrix_sdk_base::store::StoreError as StateStoreError;
20#[cfg(feature = "crypto-store")]
21use matrix_sdk_crypto::CryptoStoreError;
22use thiserror::Error;
23use tokio::io;
2425/// All the errors that can occur when opening a SQLite store.
26#[derive(Error, Debug)]
27#[non_exhaustive]
28pub enum OpenStoreError {
29/// Failed to create the DB's parent directory.
30#[error("Failed to create the database's parent directory")]
31CreateDir(#[source] io::Error),
3233/// Failed to create the DB pool.
34#[error(transparent)]
35CreatePool(#[from] CreatePoolError),
3637/// Failed to load the database's version.
38#[error("Failed to load database version")]
39LoadVersion(#[source] rusqlite::Error),
4041/// The version of the database is missing.
42#[error("Missing database version")]
43MissingVersion,
4445/// The version of the database is invalid.
46#[error("Invalid database version")]
47InvalidVersion,
4849/// Failed to apply migrations.
50#[error("Failed to run migrations")]
51Migration(#[from] Error),
5253/// Failed to get a DB connection from the pool.
54#[error(transparent)]
55Pool(#[from] PoolError),
5657/// Failed to initialize the store cipher.
58#[error("Failed to initialize the store cipher")]
59InitCipher(#[from] matrix_sdk_store_encryption::Error),
6061/// Failed to load the store cipher from the DB.
62#[error("Failed to load the store cipher from the DB")]
63LoadCipher(#[source] rusqlite::Error),
6465/// Failed to save the store cipher to the DB.
66#[error("Failed to save the store cipher to the DB")]
67SaveCipher(#[source] rusqlite::Error),
68}
6970#[derive(Debug, Error)]
71pub enum Error {
72#[error(transparent)]
73Sqlite(rusqlite::Error),
7475#[error("Failed to compute the maximum variable number from {0}")]
76SqliteMaximumVariableNumber(i32),
7778#[error(transparent)]
79Pool(PoolError),
8081#[error(transparent)]
82Encode(rmp_serde::encode::Error),
8384#[error(transparent)]
85Decode(rmp_serde::decode::Error),
8687#[error(transparent)]
88Json(#[from] serde_json::Error),
8990#[error(transparent)]
91Encryption(matrix_sdk_store_encryption::Error),
9293#[error("can't save/load sessions or group sessions in the store before an account is stored")]
94AccountUnset,
9596#[error(transparent)]
97Pickle(#[from] vodozemac::PickleError),
9899#[error("An object failed to be decrypted while unpickling")]
100Unpickle,
101102#[error("Redaction failed: {0}")]
103Redaction(#[source] ruma::canonical_json::RedactionError),
104105#[error("An update keyed by unique ID touched more than one entry")]
106InconsistentUpdate,
107108#[error("The store contains invalid data: {details}")]
109InvalidData { details: String },
110}
111112macro_rules! impl_from {
113 ( $ty:ty => $enum:ident::$variant:ident ) => {
114impl From<$ty> for $enum {
115fn from(value: $ty) -> Self {
116Self::$variant(value)
117 }
118 }
119 };
120}
121122impl_from!(rusqlite::Error => Error::Sqlite);
123impl_from!(PoolError => Error::Pool);
124impl_from!(rmp_serde::encode::Error => Error::Encode);
125impl_from!(rmp_serde::decode::Error => Error::Decode);
126impl_from!(matrix_sdk_store_encryption::Error => Error::Encryption);
127128#[cfg(feature = "crypto-store")]
129impl From<Error> for CryptoStoreError {
130fn from(e: Error) -> Self {
131 CryptoStoreError::backend(e)
132 }
133}
134135#[cfg(feature = "state-store")]
136impl From<Error> for StateStoreError {
137fn from(e: Error) -> Self {
138match e {
139 Error::Json(e) => StateStoreError::Json(e),
140 Error::Encryption(e) => StateStoreError::Encryption(e),
141 Error::Redaction(e) => StateStoreError::Redaction(e),
142 e => StateStoreError::backend(e),
143 }
144 }
145}
146147#[cfg(feature = "event-cache")]
148impl From<Error> for EventCacheStoreError {
149fn from(e: Error) -> Self {
150match e {
151 Error::Encryption(e) => EventCacheStoreError::Encryption(e),
152 e => EventCacheStoreError::backend(e),
153 }
154 }
155}
156157pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;