matrix_sdk_crypto_ffi/
error.rs1#![allow(missing_docs)]
2
3use matrix_sdk_crypto::{
4 store::{CryptoStoreError as InnerStoreError, DehydrationError as InnerDehydrationError},
5 KeyExportError, MegolmError, OlmError, SecretImportError as RustSecretImportError,
6 SignatureError as InnerSignatureError,
7};
8use matrix_sdk_sqlite::OpenStoreError;
9use ruma::{IdParseError, OwnedUserId};
10
11#[derive(Debug, thiserror::Error, uniffi::Error)]
12#[uniffi(flat_error)]
13pub enum KeyImportError {
14 #[error(transparent)]
15 Export(#[from] KeyExportError),
16 #[error(transparent)]
17 CryptoStore(#[from] InnerStoreError),
18 #[error(transparent)]
19 Json(#[from] serde_json::Error),
20}
21
22#[derive(Debug, thiserror::Error, uniffi::Error)]
23#[uniffi(flat_error)]
24pub enum SecretImportError {
25 #[error(transparent)]
26 CryptoStore(#[from] InnerStoreError),
27 #[error(transparent)]
28 Import(#[from] RustSecretImportError),
29}
30
31#[derive(Debug, thiserror::Error, uniffi::Error)]
32#[uniffi(flat_error)]
33pub enum SignatureError {
34 #[error(transparent)]
35 Signature(#[from] InnerSignatureError),
36 #[error(transparent)]
37 Identifier(#[from] IdParseError),
38 #[error(transparent)]
39 CryptoStore(#[from] InnerStoreError),
40 #[error("Unknown device {0} {1}")]
41 UnknownDevice(OwnedUserId, String),
42 #[error("Unknown user identity {0}")]
43 UnknownUserIdentity(String),
44}
45
46#[derive(Debug, thiserror::Error, uniffi::Error)]
47#[uniffi(flat_error)]
48pub enum CryptoStoreError {
49 #[error("Failed to open the store")]
50 OpenStore(#[from] OpenStoreError),
51 #[error(transparent)]
52 CryptoStore(#[from] InnerStoreError),
53 #[error(transparent)]
54 OlmError(#[from] OlmError),
55 #[error(transparent)]
56 Serialization(#[from] serde_json::Error),
57 #[error("The given string is not a valid user ID: source {0}, error {1}")]
58 InvalidUserId(String, IdParseError),
59 #[error(transparent)]
60 Identifier(#[from] IdParseError),
61 #[error(transparent)]
62 DehydrationError(#[from] InnerDehydrationError),
63}
64
65#[derive(Debug, thiserror::Error, uniffi::Error)]
66pub enum DecryptionError {
67 #[error("serialization error: {error}")]
68 Serialization { error: String },
69 #[error("identifier parsing error: {error}")]
70 Identifier { error: String },
71 #[error("megolm error: {error}")]
72 Megolm { error: String },
73 #[error("missing room key: {error}")]
74 MissingRoomKey { error: String, withheld_code: Option<String> },
75 #[error("store error: {error}")]
76 Store { error: String },
77}
78
79#[derive(Debug, thiserror::Error, uniffi::Error)]
84pub enum SecretsBundleExportError {
85 #[error(transparent)]
87 CryptoStore(CryptoStoreError),
88 #[error("The store doesn't contain all the cross-signing keys")]
90 MissingCrossSigningKeys,
91 #[error("The store contains a backup key, but no backup version")]
94 MissingBackupVersion,
95 #[error("serialization error: {error}")]
96 Serialization { error: String },
97}
98
99impl From<matrix_sdk_crypto::store::SecretsBundleExportError> for SecretsBundleExportError {
100 fn from(value: matrix_sdk_crypto::store::SecretsBundleExportError) -> Self {
101 match value {
102 matrix_sdk_crypto::store::SecretsBundleExportError::Store(e) => {
103 Self::CryptoStore(e.into())
104 }
105 matrix_sdk_crypto::store::SecretsBundleExportError::MissingCrossSigningKey(_)
106 | matrix_sdk_crypto::store::SecretsBundleExportError::MissingCrossSigningKeys => {
107 Self::MissingCrossSigningKeys
108 }
109 matrix_sdk_crypto::store::SecretsBundleExportError::MissingBackupVersion => {
110 Self::MissingBackupVersion
111 }
112 }
113 }
114}
115
116impl From<serde_json::Error> for SecretsBundleExportError {
117 fn from(err: serde_json::Error) -> Self {
118 Self::Serialization { error: err.to_string() }
119 }
120}
121
122impl From<MegolmError> for DecryptionError {
123 fn from(value: MegolmError) -> Self {
124 match &value {
125 MegolmError::MissingRoomKey(withheld_code) => Self::MissingRoomKey {
126 error: value.to_string(),
127 withheld_code: withheld_code.as_ref().map(|w| w.as_str().to_owned()),
128 },
129 _ => Self::Megolm { error: value.to_string() },
130 }
131 }
132}
133
134impl From<serde_json::Error> for DecryptionError {
135 fn from(err: serde_json::Error) -> Self {
136 Self::Serialization { error: err.to_string() }
137 }
138}
139
140impl From<IdParseError> for DecryptionError {
141 fn from(err: IdParseError) -> Self {
142 Self::Identifier { error: err.to_string() }
143 }
144}
145
146impl From<InnerStoreError> for DecryptionError {
147 fn from(err: InnerStoreError) -> Self {
148 Self::Store { error: err.to_string() }
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use assert_matches2::assert_let;
155 use matrix_sdk_crypto::MegolmError;
156
157 use super::DecryptionError;
158
159 #[test]
160 fn test_withheld_error_mapping() {
161 use matrix_sdk_common::deserialized_responses::WithheldCode;
162
163 let inner_error = MegolmError::MissingRoomKey(Some(WithheldCode::Unverified));
164
165 let binding_error: DecryptionError = inner_error.into();
166
167 assert_let!(
168 DecryptionError::MissingRoomKey { error: _, withheld_code: Some(code) } = binding_error
169 );
170 assert_eq!("m.unverified", code)
171 }
172}