newt_interaction/error.rs
1//! Protocol errors. Fail closed: none of these fall back to guessing.
2
3use thiserror::Error;
4
5/// What can go wrong constructing or reading a protocol record.
6#[derive(Debug, Error)]
7pub enum ProtocolError {
8 /// A canonical encoding or content-id operation failed.
9 #[error("content addressing failed: {0}")]
10 Identity(#[from] content_addressable::ContentError),
11 /// An id was presented in a form that is not its canonical rendering.
12 /// Accepting an alternate spelling would let two strings name one record.
13 #[error("`{presented}` is not the canonical form of this id")]
14 NonCanonicalId {
15 /// What the caller supplied.
16 presented: String,
17 },
18 /// An identifier's shape is invalid (empty, or outside the charset).
19 #[error("invalid {kind}: {reason}")]
20 InvalidId {
21 /// Which identifier kind was rejected.
22 kind: &'static str,
23 /// Why it was rejected.
24 reason: String,
25 },
26 /// A REQUIRED surface feature could not be met — either this build
27 /// does not recognize it, or the surface lacks it. Both are the same
28 /// fact to an operator: the document cannot be shown faithfully.
29 #[error(
30 "cannot present this interaction: it requires `{feature}`{}",
31 if *known { ", which this surface does not provide" }
32 else { ", which this build does not recognize" }
33 )]
34 UnsupportedFeature {
35 /// The feature name, verbatim as the document wrote it.
36 feature: String,
37 /// Whether this build recognizes the name at all.
38 known: bool,
39 },
40 /// The bytes decode, but they are not the canonical encoding of what
41 /// they decode to — reordered map keys, a non-minimal integer, an
42 /// indefinite-length string. Accepting them would mint an id different
43 /// from the one their author published.
44 #[error("non-canonical encoding of {schema} ({input_len} bytes)")]
45 NonCanonical {
46 /// The tag the record declared.
47 schema: String,
48 /// Length of the input.
49 input_len: usize,
50 },
51 /// The bytes are not a readable record. Corruption is a different fact
52 /// from a version we do not know, and is reported differently.
53 #[error("malformed record: {reason}")]
54 Malformed {
55 /// What could not be read.
56 reason: String,
57 },
58 /// A record declared a schema tag this build does not know. Unknown
59 /// REQUIRED behavior fails closed (ADR law 5).
60 #[error("unknown schema tag `{tag}` for {expected}")]
61 UnknownSchema {
62 /// The tag the record carried.
63 tag: String,
64 /// The tag this build understands.
65 expected: &'static str,
66 },
67}