Skip to main content

auths_keri/
error.rs

1use thiserror::Error;
2
3/// Errors during translation between Auths events and CESR streams.
4#[derive(Debug, Error)]
5pub enum KeriTranslationError {
6    /// A cryptographic primitive could not be CESR-encoded.
7    #[error("CESR encoding failed for {primitive_kind}: {detail}")]
8    EncodingFailed {
9        /// Which primitive type failed encoding.
10        primitive_kind: &'static str,
11        /// Details about the encoding failure.
12        detail: String,
13    },
14
15    /// A CESR-encoded primitive could not be decoded.
16    #[error("CESR decoding failed: {0}")]
17    DecodingFailed(String),
18
19    /// JSON serialization or canonicalization failed.
20    #[error("JSON serialization failed: {0}")]
21    SerializationFailed(#[from] serde_json::Error),
22
23    /// SAID computation produced a value inconsistent with the event.
24    #[error("SAID mismatch: computed {computed}, found {found}")]
25    SaidMismatch {
26        /// The SAID computed from the event body.
27        computed: String,
28        /// The SAID found in the event's `d` field.
29        found: String,
30    },
31
32    /// The version string could not be computed.
33    #[error("version string error: {0}")]
34    VersionStringError(String),
35
36    /// An event is missing required fields for CESR export.
37    #[error("event missing required field '{field}' for CESR export")]
38    MissingField {
39        /// The name of the missing field.
40        field: &'static str,
41    },
42
43    /// A signature could not be parsed from the internal format.
44    #[error("signature parse error: {0}")]
45    SignatureParseError(String),
46
47    /// Round-trip validation failed.
48    #[error("round-trip validation failed at event sequence {sequence}: {detail}")]
49    RoundTripFailed {
50        /// The event sequence number where the failure occurred.
51        sequence: u128,
52        /// Details about the round-trip failure.
53        detail: String,
54    },
55}
56
57/// Errors raised while constructing, SAID-ifying, or validating a backerless TEL.
58///
59/// A Transaction Event Log (TEL) is the KERI-native credential-status registry.
60/// These variants are distinct so a verifier can react to *why* a chain is
61/// invalid (a missing inception vs. a broken back-link vs. a tampered SAID)
62/// rather than collapsing every failure into one opaque rejection.
63#[derive(Debug, thiserror::Error, PartialEq, Eq)]
64pub enum TelError {
65    /// A `rev` event referenced a credential that was never issued in this TEL.
66    #[error("revocation references credential {credential} that was never issued")]
67    RevWithoutIss {
68        /// The credential SAID the `rev` event names.
69        credential: String,
70    },
71
72    /// An `iss` event named a registry that was not inceptioned by a leading `vcp`.
73    #[error("issuance references registry {registry} with no matching vcp inception")]
74    IssWithoutRegistry {
75        /// The registry SAID the `iss` event names.
76        registry: String,
77    },
78
79    /// The same credential was issued twice in one TEL.
80    #[error("credential {credential} issued more than once")]
81    DoubleIss {
82        /// The doubly-issued credential SAID.
83        credential: String,
84    },
85
86    /// The same credential was revoked twice in one TEL.
87    #[error("credential {credential} revoked more than once")]
88    DoubleRev {
89        /// The doubly-revoked credential SAID.
90        credential: String,
91    },
92
93    /// The prior-event back-link (`p`) or the monotonic sequence (`s`) is broken.
94    #[error("broken TEL chain for credential {credential}: {detail}")]
95    BrokenChain {
96        /// The credential SAID whose chain is broken.
97        credential: String,
98        /// Why the chain is broken (bad `p` back-link or non-monotonic `s`).
99        detail: String,
100    },
101
102    /// A TEL event's carried `d` SAID does not match a fresh recomputation.
103    #[error("TEL {event_type} SAID mismatch: computed {computed}, found {found}")]
104    SaidMismatch {
105        /// Which TEL event type mismatched (`vcp`/`iss`/`rev`).
106        event_type: &'static str,
107        /// The SAID recomputed from the event body.
108        computed: String,
109        /// The SAID carried in the event's `d` field.
110        found: String,
111    },
112
113    /// A TEL event body could not be (de)serialized or SAID-ified.
114    #[error("TEL SAID computation failed: {0}")]
115    Said(String),
116
117    /// The TEL was empty or did not begin with a `vcp` registry inception.
118    #[error("TEL must begin with a vcp registry inception")]
119    MissingInception,
120}
121
122impl From<KeriTranslationError> for TelError {
123    fn from(e: KeriTranslationError) -> Self {
124        TelError::Said(e.to_string())
125    }
126}
127
128impl From<serde_json::Error> for TelError {
129    fn from(e: serde_json::Error) -> Self {
130        TelError::Said(e.to_string())
131    }
132}