Skip to main content

auths_sdk/domains/device/
error.rs

1use auths_core::error::AuthsErrorInfo;
2use auths_verifier::types::CanonicalDid;
3use thiserror::Error;
4
5/// Errors from device linking and revocation operations.
6///
7/// Usage:
8/// ```ignore
9/// match link_result {
10///     Err(DeviceError::IdentityNotFound { did }) => { /* identity missing */ }
11///     Err(e) => return Err(e.into()),
12///     Ok(result) => { /* success */ }
13/// }
14/// ```
15#[derive(Debug, Error)]
16#[non_exhaustive]
17pub enum DeviceError {
18    /// The identity could not be found in storage.
19    #[error("identity not found: {did}")]
20    IdentityNotFound {
21        /// The DID that was not found.
22        did: String,
23    },
24
25    /// The device could not be found in attestation records.
26    #[error("device not found: {did}")]
27    DeviceNotFound {
28        /// The DID of the missing device.
29        did: String,
30    },
31
32    /// Attestation creation or validation failed.
33    #[error("attestation error: {0}")]
34    AttestationError(#[source] auths_verifier::error::AttestationError),
35
36    /// The device DID derived from the key does not match the expected DID.
37    #[error("device DID mismatch: expected {expected}, got {actual}")]
38    DeviceDidMismatch {
39        /// The expected device DID.
40        expected: String,
41        /// The actual device DID derived from the key.
42        actual: String,
43    },
44
45    /// A cryptographic operation failed.
46    #[error("crypto error: {0}")]
47    CryptoError(#[source] auths_core::AgentError),
48
49    /// A storage operation failed.
50    #[error("storage error: {0}")]
51    StorageError(#[source] crate::error::SdkStorageError),
52
53    /// Anchoring the attestation in the KEL failed.
54    #[error("anchor error: {0}")]
55    AnchorError(#[from] auths_id::keri::AnchorError),
56
57    /// Authoring or anchoring a delegated device identifier failed.
58    #[error("device delegation failed: {0}")]
59    DelegationError(#[source] auths_id::error::InitError),
60}
61
62/// Errors from device authorization extension operations.
63///
64/// Usage:
65/// ```ignore
66/// match extend_result {
67///     Err(DeviceExtensionError::AlreadyRevoked { device_did }) => { /* already gone */ }
68///     Err(e) => return Err(e.into()),
69///     Ok(result) => { /* success */ }
70/// }
71/// ```
72#[derive(Debug, Error)]
73#[non_exhaustive]
74pub enum DeviceExtensionError {
75    /// The identity could not be found in storage.
76    #[error("identity not found")]
77    IdentityNotFound,
78
79    /// No attestation exists for the specified device.
80    #[error("no attestation found for device {device_did}")]
81    NoAttestationFound {
82        /// The DID of the device with no attestation.
83        device_did: CanonicalDid,
84    },
85
86    /// The device has already been revoked.
87    #[error("device {device_did} is already revoked")]
88    AlreadyRevoked {
89        /// The DID of the revoked device.
90        device_did: CanonicalDid,
91    },
92
93    /// Creating a new attestation failed.
94    #[error("attestation creation failed: {0}")]
95    AttestationFailed(#[source] auths_verifier::error::AttestationError),
96
97    /// A storage operation failed.
98    #[error("storage error: {0}")]
99    StorageError(#[source] crate::error::SdkStorageError),
100
101    /// Anchoring the attestation in the KEL failed.
102    #[error("anchor error: {0}")]
103    AnchorError(#[from] auths_id::keri::AnchorError),
104}
105
106impl From<auths_core::AgentError> for DeviceError {
107    fn from(err: auths_core::AgentError) -> Self {
108        DeviceError::CryptoError(err)
109    }
110}
111
112impl AuthsErrorInfo for DeviceError {
113    fn error_code(&self) -> &'static str {
114        match self {
115            Self::IdentityNotFound { .. } => "AUTHS-E5101",
116            Self::DeviceNotFound { .. } => "AUTHS-E5102",
117            Self::AttestationError(_) => "AUTHS-E5103",
118            Self::DeviceDidMismatch { .. } => "AUTHS-E5105",
119            Self::CryptoError(e) => e.error_code(),
120            Self::StorageError(e) => e.error_code(),
121            Self::AnchorError(e) => e.error_code(),
122            Self::DelegationError(_) => "AUTHS-E5106",
123        }
124    }
125
126    fn suggestion(&self) -> Option<&'static str> {
127        match self {
128            Self::IdentityNotFound { .. } => Some("Run `auths init` to create an identity first"),
129            Self::DeviceNotFound { .. } => Some("Run `auths device list` to see linked devices"),
130            Self::AttestationError(_) => Some(
131                "The attestation operation failed; run `auths device list` to check device status",
132            ),
133            Self::DeviceDidMismatch { .. } => Some("Check that --device matches the key name"),
134            Self::CryptoError(e) => e.suggestion(),
135            Self::StorageError(e) => e.suggestion(),
136            Self::AnchorError(e) => e.suggestion(),
137            Self::DelegationError(_) => Some(
138                "The device delegation could not be authored or anchored; check the root identity",
139            ),
140        }
141    }
142}
143
144impl AuthsErrorInfo for DeviceExtensionError {
145    fn error_code(&self) -> &'static str {
146        match self {
147            Self::IdentityNotFound => "AUTHS-E5201",
148            Self::NoAttestationFound { .. } => "AUTHS-E5202",
149            Self::AlreadyRevoked { .. } => "AUTHS-E5203",
150            Self::AttestationFailed(_) => "AUTHS-E5204",
151            Self::StorageError(e) => e.error_code(),
152            Self::AnchorError(e) => e.error_code(),
153        }
154    }
155
156    fn suggestion(&self) -> Option<&'static str> {
157        match self {
158            Self::IdentityNotFound => Some("Run `auths init` to create an identity first"),
159            Self::NoAttestationFound { .. } => {
160                Some("Run `auths device link` to create an attestation for this device")
161            }
162            Self::AlreadyRevoked { .. } => Some(
163                "This device has been revoked and cannot be extended; link a new device with `auths device link`",
164            ),
165            Self::AttestationFailed(_) => {
166                Some("Failed to create the extension attestation; check key access and try again")
167            }
168            Self::StorageError(e) => e.suggestion(),
169            Self::AnchorError(e) => e.suggestion(),
170        }
171    }
172}