Skip to main content

lastid_sdk/error/
trust_registry.rs

1//! Trust registry specific errors.
2
3use thiserror::Error;
4
5use super::HttpError;
6use crate::trust_registry::IssuerStatus;
7
8/// Trust registry specific errors.
9#[derive(Debug, Error)]
10#[non_exhaustive]
11pub enum TrustRegistryError {
12    /// Issuer not found in trust registry
13    #[error("Issuer not found: {0}")]
14    IssuerNotFound(String),
15
16    /// Issuer status is invalid (suspended or revoked)
17    #[error("Issuer status invalid: {status:?}")]
18    InvalidIssuerStatus {
19        /// The invalid status
20        status: IssuerStatus,
21    },
22
23    /// Credential type not permitted for issuer
24    #[error("Credential type '{credential_type}' not permitted for issuer '{issuer_did}'")]
25    CredentialTypeNotPermitted {
26        /// The credential type requested
27        credential_type: String,
28        /// The issuer DID
29        issuer_did: String,
30    },
31
32    /// HTTP error from trust registry API
33    #[error("HTTP error: {0}")]
34    Http(#[from] HttpError),
35
36    /// Cache error
37    #[error("Cache error: {0}")]
38    Cache(String),
39}
40
41impl TrustRegistryError {
42    /// Check if this error is retryable.
43    #[must_use]
44    pub const fn is_retryable(&self) -> bool {
45        match self {
46            Self::Http(e) => e.is_retryable(),
47            Self::IssuerNotFound(_)
48            | Self::InvalidIssuerStatus { .. }
49            | Self::CredentialTypeNotPermitted { .. }
50            | Self::Cache(_) => false,
51        }
52    }
53
54    /// Create an issuer not found error.
55    #[must_use]
56    pub fn issuer_not_found(did: impl Into<String>) -> Self {
57        Self::IssuerNotFound(did.into())
58    }
59
60    /// Create an invalid issuer status error.
61    #[must_use]
62    pub const fn invalid_status(status: IssuerStatus) -> Self {
63        Self::InvalidIssuerStatus { status }
64    }
65
66    /// Create a credential type not permitted error.
67    #[must_use]
68    pub fn credential_not_permitted(
69        credential_type: impl Into<String>,
70        issuer_did: impl Into<String>,
71    ) -> Self {
72        Self::CredentialTypeNotPermitted {
73            credential_type: credential_type.into(),
74            issuer_did: issuer_did.into(),
75        }
76    }
77
78    /// Create a cache error.
79    #[must_use]
80    pub fn cache(message: impl Into<String>) -> Self {
81        Self::Cache(message.into())
82    }
83
84    /// Get suggested retry delay in milliseconds.
85    ///
86    /// Returns `Some(delay)` for retryable errors, `None` otherwise.
87    /// Delegates to inner `HttpError` for HTTP-related errors.
88    #[must_use]
89    pub const fn suggested_retry_delay_ms(&self) -> Option<u64> {
90        match self {
91            Self::Http(e) => e.suggested_retry_delay_ms(),
92            // Non-retryable errors don't have a suggested delay
93            Self::IssuerNotFound(_)
94            | Self::InvalidIssuerStatus { .. }
95            | Self::CredentialTypeNotPermitted { .. }
96            | Self::Cache(_) => None,
97        }
98    }
99
100    /// Get the error category for metrics and logging.
101    #[must_use]
102    pub const fn category(&self) -> &'static str {
103        match self {
104            Self::IssuerNotFound(_) => "issuer_not_found",
105            Self::InvalidIssuerStatus { .. } => "invalid_issuer_status",
106            Self::CredentialTypeNotPermitted { .. } => "credential_type_not_permitted",
107            Self::Http(_) => "http",
108            Self::Cache(_) => "cache",
109        }
110    }
111}