dig_urn_resolver/error.rs
1//! The resolver's error taxonomy.
2//!
3//! Two failure classes are deliberately kept apart (see the module docs on
4//! [`crate::resolver`]):
5//!
6//! * **Hard, fail-closed errors** — [`ResolveError`] — a malformed URN, a
7//! not-found resource, or a verify/decrypt failure. A verify failure means the
8//! served bytes did not chain to the trusted on-chain root (tampered / decoy):
9//! the resolver NEVER returns those bytes, it fails closed.
10//! * **The network-unreachable state** — NOT an error. When every transport tier
11//! is unreachable the resolver returns a branded HTML document via
12//! [`crate::ResolvedData`] with `unreachable == true`, so a consuming webview can
13//! render a friendly "connect a node" page instead of a crash.
14
15use thiserror::Error;
16
17/// A hard, fail-closed resolution failure. Distinct from the network-unreachable
18/// state, which is a successful [`crate::ResolvedData`] carrying a branded page.
19#[derive(Debug, Error)]
20pub enum ResolveError {
21 /// The input was not a syntactically valid DIG URN.
22 #[error("invalid DIG URN: {0}")]
23 Parse(String),
24
25 /// A transport-level failure talking to a specific endpoint (DNS, TLS,
26 /// connection, timeout, malformed HTTP). Not the same as "every tier down"
27 /// (that is the unreachable state), nor a not-found (that is [`Self::NotFound`]).
28 #[error("transport error: {0}")]
29 Transport(String),
30
31 /// The RPC endpoint returned a JSON-RPC / protocol error, or a malformed
32 /// response the resolver cannot interpret.
33 #[error("rpc error: {0}")]
34 Rpc(String),
35
36 /// The resource does not exist in the store at the resolved root. A hard,
37 /// fail-closed verdict — never masked behind a friendly page.
38 #[error("resource not found")]
39 NotFound,
40
41 /// A rootless URN was resolved over the untrusted rpc tier, where the trust root
42 /// cannot be established without trusting the gateway. Pin a root in the URN
43 /// (`urn:dig:chia:<store>:<root>/<path>`), or resolve via a loopback node. A
44 /// hard, fail-closed error — the resolver will not verify against a
45 /// gateway-asserted root.
46 #[error("a root-pinned URN is required to resolve over the public gateway (rootless URNs are not chain-verified there)")]
47 RootRequired,
48
49 /// The served ciphertext failed integrity verification against the
50 /// chain-anchored root (tampered bytes, a non-chaining proof, or a decoy from
51 /// a wrong store). FAIL-CLOSED: the bytes are discarded, never returned.
52 #[error("inclusion verification failed: {0}")]
53 VerifyFailed(String),
54
55 /// The verified ciphertext did not decrypt under the URN's key (AES-256-GCM-SIV
56 /// tag failure — wrong key/salt or corruption). FAIL-CLOSED.
57 #[error("decryption failed (wrong key/salt or corrupt ciphertext)")]
58 DecryptFailed,
59}
60
61/// Result alias for resolver operations.
62pub type Result<T> = core::result::Result<T, ResolveError>;