Skip to main content

tenzro_identity/
error.rs

1//! Error types for the Tenzro Decentralized Identity Protocol
2
3use thiserror::Error;
4
5/// Result type for identity operations
6pub type Result<T> = std::result::Result<T, IdentityError>;
7
8/// Errors that can occur during identity operations
9#[derive(Debug, Error)]
10pub enum IdentityError {
11    /// DID could not be parsed
12    #[error("invalid DID format: {0}")]
13    InvalidDid(String),
14
15    /// Identity not found in the registry
16    #[error("identity not found: {0}")]
17    NotFound(String),
18
19    /// Identity already exists
20    #[error("identity already exists: {0}")]
21    AlreadyExists(String),
22
23    /// Identity is not in the required state
24    #[error("identity is not active: {0}")]
25    NotActive(String),
26
27    /// Operation not permitted
28    #[error("permission denied: {0}")]
29    PermissionDenied(String),
30
31    /// Delegation scope violated
32    #[error("delegation scope violation: {0}")]
33    DelegationViolation(String),
34
35    /// Credential error
36    #[error("credential error: {0}")]
37    CredentialError(String),
38
39    /// Verification failed
40    #[error("verification failed: {0}")]
41    VerificationFailed(String),
42
43    /// Trust chain is broken — an issuer in the chain is not Active,
44    /// is not in the registry, has no key the credential could verify
45    /// against, or its signature does not verify (CRITICAL #41).
46    #[error("trust chain broken at issuer {issuer}: {reason}")]
47    TrustChainBroken {
48        /// DID of the issuer where the chain broke
49        issuer: String,
50        /// Human-readable reason
51        reason: String,
52    },
53
54    /// A cycle was detected during trust chain traversal (CRITICAL #41).
55    /// Contains the DID that was revisited.
56    #[error("trust chain cycle detected at issuer {issuer}")]
57    TrustChainCycle {
58        /// DID that completed the cycle
59        issuer: String,
60    },
61
62    /// Trust chain exceeded the configured maximum traversal depth
63    /// (CRITICAL #41). Acts as a DoS guard against arbitrarily long
64    /// or maliciously crafted issuer chains.
65    #[error("trust chain exceeded max depth of {max_depth}")]
66    TrustChainTooDeep {
67        /// Maximum depth allowed by the verifier configuration
68        max_depth: usize,
69    },
70
71    /// Trust chain terminated without reaching a recognized trust root
72    /// (CRITICAL #41). The credential chain is internally consistent but
73    /// does not anchor to any DID the verifier was configured to trust.
74    #[error("trust chain did not reach a recognized trust root")]
75    NoTrustRoot,
76
77    /// Invalid service endpoint URL (MEDIUM #128)
78    #[error("invalid service endpoint: {0}")]
79    InvalidServiceEndpoint(String),
80
81    /// Credential already issued / replay attempt (MEDIUM #129)
82    #[error("duplicate credential: {0}")]
83    DuplicateCredential(String),
84
85    /// Username is already taken by another identity
86    #[error("username already taken: {0}")]
87    UsernameTaken(String),
88
89    /// Username does not meet validation requirements
90    #[error("invalid username: {0}")]
91    UsernameInvalid(String),
92
93    /// Wallet provisioning or binding error
94    #[error("wallet error: {0}")]
95    WalletError(String),
96
97    /// Caller-supplied public key was malformed (wrong length, wrong
98    /// curve, etc.). Used by BYOK registration paths.
99    #[error("invalid public key: {0}")]
100    InvalidPublicKey(String),
101
102    /// Cryptographic operation failed
103    #[error("crypto error: {0}")]
104    CryptoError(String),
105
106    /// Serialization/deserialization error
107    #[error("serialization error: {0}")]
108    SerializationError(String),
109}
110
111impl From<tenzro_crypto::CryptoError> for IdentityError {
112    fn from(e: tenzro_crypto::CryptoError) -> Self {
113        IdentityError::CryptoError(e.to_string())
114    }
115}
116
117impl From<tenzro_wallet::WalletError> for IdentityError {
118    fn from(e: tenzro_wallet::WalletError) -> Self {
119        IdentityError::WalletError(e.to_string())
120    }
121}
122
123impl From<serde_json::Error> for IdentityError {
124    fn from(e: serde_json::Error) -> Self {
125        IdentityError::SerializationError(e.to_string())
126    }
127}