Skip to main content

slim_mls/
errors.rs

1// Copyright AGNTCY Contributors (https://github.com/agntcy)
2// SPDX-License-Identifier: Apache-2.0
3
4use mls_rs::error::IntoAnyError;
5use slim_auth::errors::AuthError;
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum MlsError {
10    // I/O / serialization
11    #[error("i/o error")]
12    Io(#[from] std::io::Error),
13    #[error("serialization/deserialization error")]
14    Serde(#[from] serde_json::Error),
15
16    // Underlying MLS library
17    #[error("mls error")]
18    Mls(#[from] mls_rs::error::MlsError),
19
20    // Crypto / provider
21    #[error("crypto provider error: {0}")]
22    CryptoProviderError(String),
23
24    // Auth / identity provider
25    #[error("identity provider error: {0}")]
26    IdentityProviderError(#[from] AuthError),
27
28    // Ciphersuite / client / group lifecycle
29    #[error("requested ciphersuite is unavailable")]
30    CiphersuiteUnavailable,
31    #[error("mls client not initialized")]
32    ClientNotInitialized,
33    #[error("mls group does not exist")]
34    GroupNotExists,
35
36    // Payload expectations
37    #[error("no mls update payload found")]
38    NoGroupUpdatePayload,
39    #[error("no welcome message generated")]
40    NoWelcomeMessage,
41    #[error("unknown payload type")]
42    UnknownPayloadType,
43
44    // Storage / identity persistence
45    #[error("failed to create storage directory: {0}")]
46    StorageIo(std::io::Error),
47    #[error("failed to get token: {0}")]
48    TokenRetrievalFailed(String),
49    #[error("failed to sync file: {0}")]
50    FileSyncFailed(String),
51    #[error("identifier not found: {0}")]
52    IdentifierNotFound(String),
53    #[error("credential not found in stored identity")]
54    CredentialNotFound,
55
56    // Identity / claims (merged from SlimIdentityError)
57    #[error("not a basic credential")]
58    NotBasicCredential,
59    #[error("invalid UTF-8 in credential")]
60    InvalidUtf8(#[from] std::str::Utf8Error),
61    #[error("identity verification failed: {0}")]
62    VerificationFailed(String),
63    #[error("external sender validation failed: {0}")]
64    ExternalSenderFailed(String),
65    #[error(
66        "public key mismatch: identity public key does not match provided public key: expected: {expected}, found: {found}"
67    )]
68    PublicKeyMismatch { expected: String, found: String },
69    #[error("external commit not supported")]
70    ExternalCommitNotSupported,
71}
72
73impl IntoAnyError for MlsError {}
74
75impl MlsError {
76    /// Helper to construct a crypto provider error from any error implementing std::error::Error.
77    pub fn crypto_provider<E: std::error::Error + Send + Sync + 'static>(e: E) -> Self {
78        MlsError::CryptoProviderError(e.to_string())
79    }
80
81    /// Helper to construct a token retrieval failure from any displayable value.
82    pub fn token_retrieval_failed<T: std::fmt::Display>(t: T) -> Self {
83        MlsError::TokenRetrievalFailed(t.to_string())
84    }
85
86    /// Helper to construct an identifier not found error.
87    pub fn identifier_not_found<I: std::fmt::Display>(id: I) -> Self {
88        MlsError::IdentifierNotFound(id.to_string())
89    }
90
91    /// Helper to construct a verification failed error.
92    pub fn verification_failed<R: std::fmt::Display>(reason: R) -> Self {
93        MlsError::VerificationFailed(reason.to_string())
94    }
95
96    /// Helper to construct an external sender validation failure.
97    pub fn external_sender_failed<R: std::fmt::Display>(reason: R) -> Self {
98        MlsError::ExternalSenderFailed(reason.to_string())
99    }
100}