bc_envelope/base/
error.rs

1use thiserror::Error;
2
3/// Error types returned when operating on Gordian Envelopes.
4///
5/// These errors capture various conditions that can occur when working with envelopes,
6/// including structure validation, operation constraints, and extension-specific errors.
7///
8/// The errors are organized by category, reflecting the base envelope specification
9/// and various extensions defined in the Gordian Envelope Internet Draft and Blockchain
10/// Commons Research (BCR) documents.
11#[derive(Debug, Error)]
12pub enum Error {
13    //
14    // Base Specification
15    //
16
17    /// Returned when attempting to compress or encrypt an envelope that has already been elided.
18    ///
19    /// This error occurs because an elided envelope only contains a digest reference and no longer
20    /// has a subject that can be compressed or encrypted.
21    #[error("envelope was elided, so it cannot be compressed or encrypted")]
22    AlreadyElided,
23
24    /// Returned when attempting to retrieve an assertion by predicate, but multiple matching
25    /// assertions exist.
26    ///
27    /// For queries that expect a single result (like `object_for_predicate`), having multiple
28    /// matching assertions is ambiguous and requires more specific targeting.
29    #[error("more than one assertion matches the predicate")]
30    AmbiguousPredicate,
31
32    /// Returned when a digest validation fails.
33    ///
34    /// This can occur when unwrapping an envelope, verifying signatures, or other operations
35    /// that rely on the integrity of envelope digests.
36    #[error("digest did not match")]
37    InvalidDigest,
38
39    /// Returned when an envelope's format is invalid.
40    ///
41    /// This typically occurs during parsing or decoding of an envelope from CBOR.
42    #[error("invalid format")]
43    InvalidFormat,
44
45    /// Returned when a digest is expected but not found.
46    ///
47    /// This can occur when working with envelope structures that require digest information,
48    /// such as when working with elided envelopes.
49    #[error("a digest was expected but not found")]
50    MissingDigest,
51
52    /// Returned when attempting to retrieve an assertion by predicate, but no matching
53    /// assertion exists.
54    ///
55    /// This error occurs with functions like `object_for_predicate` when the specified
56    /// predicate doesn't match any assertion in the envelope.
57    #[error("no assertion matches the predicate")]
58    NonexistentPredicate,
59
60    /// Returned when attempting to unwrap an envelope that wasn't wrapped.
61    ///
62    /// This error occurs when calling `Envelope::unwrap_envelope` on an envelope
63    /// that doesn't have the wrapped format.
64    #[error("cannot unwrap an envelope that was not wrapped")]
65    NotWrapped,
66
67    /// Returned when expecting an envelope's subject to be a leaf, but it isn't.
68    ///
69    /// This error occurs when calling methods that require access to a leaf value
70    /// but the envelope's subject is an assertion, node, or elided.
71    #[error("the envelope's subject is not a leaf")]
72    NotLeaf,
73
74    /// Returned when expecting an envelope's subject to be an assertion, but it isn't.
75    ///
76    /// This error occurs when calling methods that require an assertion structure
77    /// but the envelope's subject has a different format.
78    #[error("the envelope's subject is not an assertion")]
79    NotAssertion,
80
81    /// Returned
82    #[error("assertion must be a map with exactly one element")]
83    InvalidAssertion,
84
85    //
86    // Attachments Extension
87    //
88
89    /// Returned when an attachment's format is invalid.
90    ///
91    /// This error occurs when an envelope contains an attachment with an invalid structure
92    /// according to the Envelope Attachment specification (BCR-2023-006).
93    #[cfg(feature = "attachment")]
94    #[error("invalid attachment")]
95    InvalidAttachment,
96
97    /// Returned when an attachment is requested but does not exist.
98    ///
99    /// This error occurs when attempting to retrieve an attachment by ID that
100    /// doesn't exist in the envelope.
101    #[cfg(feature = "attachment")]
102    #[error("nonexistent attachment")]
103    NonexistentAttachment,
104
105    /// Returned when multiple attachments match a single query.
106    ///
107    /// This error occurs when multiple attachments have the same ID, making
108    /// it ambiguous which attachment should be returned.
109    #[cfg(feature = "attachment")]
110    #[error("abiguous attachment")]
111    AmbiguousAttachment,
112
113    //
114    // Compression Extension
115    //
116
117    /// Returned when attempting to compress an envelope that is already compressed.
118    ///
119    /// This error occurs when calling compression functions on an envelope that
120    /// already has compressed content, as defined in BCR-2023-005.
121    #[cfg(feature = "compress")]
122    #[error("envelope was already compressed")]
123    AlreadyCompressed,
124
125    /// Returned when attempting to uncompress an envelope that is not compressed.
126    ///
127    /// This error occurs when calling uncompression functions on an envelope that
128    /// doesn't contain compressed content.
129    #[cfg(feature = "compress")]
130    #[error("cannot uncompress an envelope that was not compressed")]
131    NotCompressed,
132
133    //
134    // Symmetric Encryption Extension
135    //
136
137    /// Returned when attempting to encrypt an envelope that is already encrypted or compressed.
138    ///
139    /// This error occurs to prevent multiple layers of encryption or encryption of
140    /// compressed data, which could reduce security, as defined in BCR-2023-004.
141    #[cfg(feature = "encrypt")]
142    #[error("envelope was already encrypted or compressed, so it cannot be encrypted")]
143    AlreadyEncrypted,
144
145    /// Returned when attempting to decrypt an envelope that is not encrypted.
146    ///
147    /// This error occurs when calling decryption functions on an envelope that
148    /// doesn't contain encrypted content.
149    #[cfg(feature = "encrypt")]
150    #[error("cannot decrypt an envelope that was not encrypted")]
151    NotEncrypted,
152
153    //
154    // Known Values Extension
155    //
156
157    /// Returned when expecting an envelope's subject to be a known value, but it isn't.
158    ///
159    /// This error occurs when calling methods that require a known value (as defined in
160    /// BCR-2023-003) but the envelope's subject is a different type.
161    #[cfg(feature = "known_value")]
162    #[error("the envelope's subject is not a known value")]
163    NotKnownValue,
164
165    //
166    // Public Key Encryption Extension
167    //
168
169    /// Returned when attempting to decrypt an envelope with a recipient that doesn't match.
170    ///
171    /// This error occurs when trying to use a private key to decrypt an envelope that
172    /// wasn't encrypted for the corresponding public key.
173    #[cfg(feature = "recipient")]
174    #[error("unknown recipient")]
175    UnknownRecipient,
176
177    //
178    // Encrypted Key Extension
179    //
180
181    /// Returned when attempting to decrypt an envelope with a secret that
182    /// doesn't match.
183    ///
184    /// This error occurs when trying to use a secret that does not correspond
185    /// to the expected recipient, preventing successful decryption.
186    #[cfg(feature = "secret")]
187    #[error("secret not found")]
188    UnknownSecret,
189
190    //
191    // Public Key Signing Extension
192    //
193
194    /// Returned when a signature verification fails.
195    ///
196    /// This error occurs when a signature does not validate against its purported
197    /// public key.
198    #[cfg(feature = "signature")]
199    #[error("could not verify a signature")]
200    UnverifiedSignature,
201
202    /// Returned when the outer signature object type is not `Signature`.
203    #[cfg(feature = "signature")]
204    #[error("unexpected outer signature object type")]
205    InvalidOuterSignatureType,
206
207    /// Returned when the inner signature object type is not `Signature`.
208    #[cfg(feature = "signature")]
209    #[error("unexpected inner signature object type")]
210    InvalidInnerSignatureType,
211
212    /// Returned when the inner signature is not made with the same key as the outer signature.
213    #[cfg(feature = "signature")]
214    #[error("inner signature not made with same key as outer signature")]
215    UnverifiedInnerSignature,
216
217    /// Returned when the signature object is not a `Signature`.
218    #[cfg(feature = "signature")]
219    #[error("unexpected signature object type")]
220    InvalidSignatureType,
221
222    //
223    // SSKR Extension
224    //
225
226    /// Returned when SSKR shares are invalid or insufficient for reconstruction.
227    ///
228    /// This error occurs when attempting to join SSKR shares that are malformed,
229    /// from different splits, or insufficient to meet the recovery threshold.
230    #[cfg(feature = "sskr")]
231    #[error("invalid SSKR shares")]
232    InvalidShares,
233
234    //
235    // Types Extension
236    //
237
238    /// Returned when an envelope contains an invalid type.
239    ///
240    /// This error occurs when an envelope's type information doesn't match
241    /// the expected format or value.
242    #[cfg(feature = "types")]
243    #[error("invalid type")]
244    InvalidType,
245
246    /// Returned when an envelope contains ambiguous type information.
247    ///
248    /// This error occurs when multiple type assertions exist that conflict
249    /// with each other or create ambiguity about the envelope's type.
250    #[cfg(feature = "types")]
251    #[error("ambiguous type")]
252    AmbiguousType,
253
254    //
255    // Expressions Extension
256    //
257
258    /// Returned when a response envelope has an unexpected ID.
259    ///
260    /// This error occurs when processing a response envelope and the ID doesn't
261    /// match the expected request ID, as defined in BCR-2023-012.
262    #[cfg(feature = "expression")]
263    #[error("unexpected response ID")]
264    UnexpectedResponseID,
265
266    /// Returned when a response envelope is invalid.
267    #[cfg(feature = "expression")]
268    #[error("invalid response")]
269    InvalidResponse,
270
271    /// dcbor error
272    #[error("dcbor error: {0}")]
273    DCBOR(#[from] dcbor::Error),
274}
275
276pub type Result<T> = std::result::Result<T, Error>;