core_crypto/error/
mod.rs

1mod cryptobox_migration;
2mod keystore;
3mod leaf;
4mod mls;
5mod proteus;
6mod recursive;
7mod wrapper;
8
9pub use cryptobox_migration::{CryptoboxMigrationError, CryptoboxMigrationErrorKind};
10pub use keystore::KeystoreError;
11pub use leaf::LeafError;
12pub use mls::{MlsError, MlsErrorKind};
13pub use proteus::{ProteusError, ProteusErrorKind};
14pub use recursive::{RecursiveError, ToRecursiveError};
15pub(crate) use wrapper::WrappedContextualError;
16
17/// A module-specific [Result][core::result::Result] type with a default error variant.
18pub type Result<T, E = Error> = core::result::Result<T, E>;
19
20/// Errors produced by the root module group
21#[derive(Debug, thiserror::Error)]
22pub enum Error {
23    /// Invalid [crate::transaction_context::TransactionContext]. This context has been finished and can no longer be used.
24    #[error("This transaction context has already been finished and can no longer be used.")]
25    InvalidTransactionContext,
26    /// The proteus client has been called but has not been initialized yet
27    #[error("Proteus client hasn't been initialized")]
28    ProteusNotInitialized,
29    /// Mls Transport Callbacks were not provided
30    #[error("The mls transport callbacks needed for CoreCrypto to operate were not set")]
31    MlsTransportNotProvided,
32    /// Any error that occurs during mls transport.
33    #[error("Error during mls transport: {0}")]
34    ErrorDuringMlsTransport(String),
35    /// This item requires a feature that the core-crypto library was built without
36    #[error("This item requires a feature that the core-crypto library was built without: {0}")]
37    FeatureDisabled(&'static str),
38    /// A key store operation failed
39    #[error(transparent)]
40    Keystore(#[from] KeystoreError),
41    /// Invalid history secret
42    #[error("Invalid history secret: {0}")]
43    InvalidHistorySecret(&'static str),
44    /// An external MLS operation failed
45    #[error(transparent)]
46    Mls(#[from] MlsError),
47    /// A Proteus operation failed
48    #[error(transparent)]
49    Proteus(#[from] ProteusError),
50    /// A cryptobox migration operation failed
51    #[error(transparent)]
52    CryptoboxMigration(#[from] CryptoboxMigrationError),
53    /// A crate-internal operation failed
54    #[error(transparent)]
55    Recursive(#[from] RecursiveError),
56}
57
58/// Produce the error message from the innermost wrapped error.
59///
60/// We produce arbitrarily nested errors which are very helpful
61/// at capturing relevant context, and very bad at surfacing the
62/// root error cause in a default `.to_string()` call.
63///
64/// This trait, automatically implemented for all standard errors,
65/// rectifies this problem.
66pub trait InnermostErrorMessage {
67    /// Produce the error message from the innermost wrapped error.
68    fn innermost_error_message(&self) -> String;
69}
70
71impl<E: std::error::Error> InnermostErrorMessage for E {
72    fn innermost_error_message(&self) -> String {
73        let mut err: &dyn std::error::Error = self;
74        while let Some(source) = err.source() {
75            err = source;
76        }
77        err.to_string()
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn can_unpack_wrapped_error() {
87        let inner = Error::InvalidTransactionContext;
88        let outer = RecursiveError::root("wrapping the inner for test purposes")(inner);
89        let message = outer.innermost_error_message();
90        assert_eq!(message, Error::InvalidTransactionContext.to_string());
91    }
92}