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