Skip to main content

soroban_fork/
error.rs

1//! Error types for the `soroban-fork` crate.
2//!
3//! Every fallible operation in the public API returns [`Result<T, ForkError>`]
4//! (aliased as [`Result<T>`]). Errors are typed so callers can discriminate
5//! transport failures from cache-file problems from XDR-decode problems,
6//! rather than grepping stringly-typed errors.
7
8use std::path::PathBuf;
9
10/// The crate's unified error type.
11#[derive(Debug, thiserror::Error)]
12#[non_exhaustive]
13pub enum ForkError {
14    /// A JSON-RPC HTTP request failed (network error, timeout, or non-success
15    /// status after all retries).
16    #[error("RPC transport error: {0}")]
17    Transport(String),
18
19    /// The RPC endpoint returned a JSON-RPC level error object.
20    #[error("RPC returned error: {0}")]
21    RpcError(String),
22
23    /// The RPC response was well-formed JSON but didn't contain a `result`
24    /// field (protocol violation on the server side).
25    #[error("RPC response had no result field")]
26    RpcNoResult,
27
28    /// An XDR payload failed to encode or decode. Usually indicates an
29    /// incompatibility between the pinned `stellar-xdr` version and the
30    /// protocol version the RPC server is serving.
31    #[error("XDR codec error: {0}")]
32    Xdr(String),
33
34    /// A base64 payload from the RPC failed to decode.
35    #[error("base64 decode error: {0}")]
36    Base64(#[from] base64::DecodeError),
37
38    /// JSON (de)serialization error.
39    #[error("JSON codec error: {0}")]
40    Json(#[from] serde_json::Error),
41
42    /// Reading or writing the on-disk cache snapshot failed.
43    #[error("cache I/O error at {path}: {message}")]
44    Cache {
45        /// The path we were trying to read or write.
46        path: PathBuf,
47        /// The underlying I/O-or-serialization error, stringified because
48        /// [`soroban_ledger_snapshot`] returns a non-`std::error::Error`
49        /// type for its file operations. Not named `source` so thiserror
50        /// doesn't confuse it with the error-chain source attribute.
51        message: String,
52    },
53
54    /// An out-of-band operation on the underlying soroban-env-host failed.
55    ///
56    /// Currently only emitted by [`super::ForkConfig::tracing`] when
57    /// switching the host's diagnostic level. Per-call contract failures
58    /// surface as panics from `Env::invoke_contract` and never travel
59    /// through this enum — that's an SDK boundary we don't reach across.
60    #[error("host operation failed: {0}")]
61    Host(String),
62
63    /// Building or locating a workspace member's contract WASM failed.
64    ///
65    /// Emitted by [`super::workspace_wasm`] when `cargo metadata` /
66    /// `cargo build` fails, when the named crate isn't a workspace
67    /// member, or when the expected `.wasm` artifact is missing or
68    /// unreadable after a successful build. The message carries the
69    /// underlying cause verbatim — compilation errors from cargo
70    /// surface as-is so the failing test reports them straight.
71    #[error("workspace contract build error: {0}")]
72    Workspace(String),
73}
74
75impl From<reqwest::Error> for ForkError {
76    fn from(value: reqwest::Error) -> Self {
77        Self::Transport(value.to_string())
78    }
79}
80
81/// Convenience alias — every public API returns this.
82pub type Result<T> = std::result::Result<T, ForkError>;