metaflux_client/error.rs
1//! Crate-wide error type.
2//!
3//! Every fallible SDK operation returns [`Result<T, ClientError>`]. The
4//! variants are deliberately coarse — enough to discriminate the failure
5//! mode for retry policy, but not so granular that callers have to match on
6//! every wire field.
7
8use thiserror::Error;
9
10/// The single error type returned by every fallible operation in this SDK.
11#[derive(Debug, Error)]
12#[non_exhaustive]
13pub enum ClientError {
14 /// Client setup failure (bad URL, TLS init, etc.).
15 #[error("client builder error: {0}")]
16 Builder(String),
17
18 /// HTTP transport failure (connection refused, timeout, etc.).
19 #[error("HTTP error: {0}")]
20 Http(#[from] reqwest::Error),
21
22 /// JSON encode / decode failure.
23 #[error("decode error: {0}")]
24 Decode(#[from] serde_json::Error),
25
26 /// The server returned an error envelope with a code + message.
27 ///
28 /// `code` is the HTTP status code; `msg` is the `error` field from the
29 /// MTF-native error envelope (`{"error": "..."}`).
30 #[error("protocol error ({code}): {msg}")]
31 ProtocolError {
32 /// HTTP status code returned by the server.
33 code: u16,
34 /// Error message from the server's error envelope.
35 msg: String,
36 },
37
38 /// EIP-712 signature production failed.
39 #[error("signature error: {0}")]
40 Signature(String),
41
42 /// The signature recovered does not match the wallet's address.
43 ///
44 /// This indicates an internal bug — the SDK signed a message but
45 /// recovering the signer from the digest + signature did not yield the
46 /// expected address. Should never happen in practice.
47 #[error("signature mismatch: expected signer {expected}, recovered {recovered}")]
48 SignatureMismatch {
49 /// Expected signer address (hex, no 0x prefix).
50 expected: String,
51 /// Recovered signer address (hex, no 0x prefix).
52 recovered: String,
53 },
54
55 /// Private key parsing failed (wrong length / not hex / out of curve).
56 #[error("invalid key: {0}")]
57 InvalidKey(String),
58
59 /// WebSocket transport failure.
60 #[error("websocket error: {0}")]
61 WebSocket(String),
62
63 /// User input failed local validation before any network call.
64 #[error("validation error: {0}")]
65 Validation(String),
66}
67
68impl From<k256::ecdsa::Error> for ClientError {
69 fn from(e: k256::ecdsa::Error) -> Self {
70 Self::Signature(e.to_string())
71 }
72}
73
74impl From<tokio_tungstenite::tungstenite::Error> for ClientError {
75 fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
76 Self::WebSocket(e.to_string())
77 }
78}