actpub_nodeinfo/error.rs
1//! Error types for [`actpub-nodeinfo`](crate).
2
3use thiserror::Error;
4
5/// All failure modes for this crate.
6#[derive(Debug, Error)]
7#[non_exhaustive]
8pub enum Error {
9 /// A URL could not be parsed.
10 #[error("invalid URL: {0}")]
11 InvalidUrl(#[from] url::ParseError),
12
13 /// The requested schema version was not advertised by the server.
14 #[error("requested NodeInfo version {requested} not advertised by server")]
15 VersionNotAdvertised {
16 /// The requested version.
17 requested: &'static str,
18 },
19
20 /// An HTTP transport error.
21 #[cfg(feature = "client")]
22 #[cfg_attr(docsrs, doc(cfg(feature = "client")))]
23 #[error("HTTP error: {0}")]
24 Http(#[from] reqwest::Error),
25
26 /// The server responded with a non-success status.
27 #[cfg(feature = "client")]
28 #[cfg_attr(docsrs, doc(cfg(feature = "client")))]
29 #[error("NodeInfo server returned status {0}")]
30 BadStatus(u16),
31
32 /// The response body exceeded the configured maximum size. Raised
33 /// only by the client helpers, which cap incoming bodies to a
34 /// generous default (see
35 /// [`DEFAULT_MAX_BODY_BYTES`](crate::DEFAULT_MAX_BODY_BYTES)).
36 #[cfg(feature = "client")]
37 #[cfg_attr(docsrs, doc(cfg(feature = "client")))]
38 #[error("NodeInfo response body exceeds the {0}-byte limit")]
39 ResponseTooLarge(u64),
40
41 /// The response body could not be parsed as JSON.
42 #[error("JSON error: {0}")]
43 Json(#[from] serde_json::Error),
44
45 /// The discovery document advertised a `NodeInfo` document URL
46 /// whose origin (scheme + host + port) does not match the
47 /// `host` the discovery fetch was directed at.
48 ///
49 /// This defends against an SSRF pivot where an attacker serves
50 /// `/.well-known/nodeinfo` pointing at a cloud-metadata or
51 /// loopback URL; [`fetch_with_limit`](crate::fetch_with_limit)
52 /// refuses to follow the cross-origin hop before it reaches
53 /// the transport.
54 #[cfg(feature = "client")]
55 #[cfg_attr(docsrs, doc(cfg(feature = "client")))]
56 #[error(
57 "NodeInfo discovery at `{discovery}` advertised a cross-origin href `{href}`; \
58 refusing to follow"
59 )]
60 CrossOriginHref {
61 /// The trusted host the discovery document was fetched from.
62 discovery: url::Url,
63 /// The attacker-controlled href the discovery tried to send us to.
64 href: url::Url,
65 },
66}