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}