1use thiserror::Error;
4
5#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
6#[derive(Debug, Clone, PartialEq, Eq, Error, serde::Serialize)]
7pub enum FormatFailure {
8 #[error("invalid input: {message}")]
9 InvalidInput { message: String, retryable: bool },
10
11 #[error("invalid descriptor: {message}")]
12 InvalidDescriptor { message: String, retryable: bool },
13
14 #[error("resolution failed: {message}")]
15 ResolutionFailed { message: String, retryable: bool },
16
17 #[error("internal error: {message}")]
18 Internal { message: String, retryable: bool },
19}
20
21#[derive(Debug, Error)]
23pub enum Error {
24 #[error("decode error: {0}")]
25 Decode(#[from] DecodeError),
26
27 #[error("descriptor error: {0}")]
28 Descriptor(String),
29
30 #[error("resolve error: {0}")]
31 Resolve(#[from] ResolveError),
32
33 #[error("token registry error: {0}")]
34 TokenRegistry(String),
35
36 #[error("render error: {0}")]
37 Render(String),
38}
39
40#[derive(Debug, Error)]
42pub enum DecodeError {
43 #[error("invalid function signature: {0}")]
44 InvalidSignature(String),
45
46 #[error("calldata too short: expected at least {expected} bytes, got {actual}")]
47 CalldataTooShort { expected: usize, actual: usize },
48
49 #[error("selector mismatch: expected {expected}, got {actual}")]
50 SelectorMismatch { expected: String, actual: String },
51
52 #[error("invalid ABI encoding: {0}")]
53 InvalidEncoding(String),
54
55 #[error("unsupported type: {0}")]
56 UnsupportedType(String),
57}
58
59#[derive(Debug, Error)]
61pub enum ResolveError {
62 #[error("descriptor not found for chain_id={chain_id}, address={address}")]
63 NotFound { chain_id: u64, address: String },
64
65 #[error("registry index missing: {url}")]
66 RegistryIndexMissing { url: String },
67
68 #[error("registry descriptor missing: {url}")]
69 RegistryDescriptorMissing { url: String },
70
71 #[error("registry io error: {0}")]
72 RegistryIo(String),
73
74 #[error("parse error: {0}")]
75 Parse(String),
76}
77
78impl From<Error> for FormatFailure {
79 fn from(value: Error) -> Self {
80 match value {
81 Error::Decode(err) => Self::InvalidInput {
82 message: err.to_string(),
83 retryable: false,
84 },
85 Error::Descriptor(message) => Self::InvalidDescriptor {
86 message,
87 retryable: false,
88 },
89 Error::Resolve(err) => err.into(),
90 Error::TokenRegistry(message) => Self::ResolutionFailed {
91 message: format!("token registry error: {message}"),
92 retryable: true,
93 },
94 Error::Render(message) => Self::InvalidDescriptor {
95 message,
96 retryable: false,
97 },
98 }
99 }
100}
101
102impl From<ResolveError> for FormatFailure {
103 fn from(value: ResolveError) -> Self {
104 match value {
105 ResolveError::NotFound { chain_id, address } => Self::InvalidDescriptor {
106 message: format!("descriptor not found for chain_id={chain_id}, address={address}"),
107 retryable: false,
108 },
109 ResolveError::RegistryIndexMissing { url } => Self::ResolutionFailed {
110 message: format!("registry index missing: {url}"),
111 retryable: true,
112 },
113 ResolveError::RegistryDescriptorMissing { url } => Self::ResolutionFailed {
114 message: format!("registry descriptor missing: {url}"),
115 retryable: true,
116 },
117 ResolveError::RegistryIo(message) => Self::ResolutionFailed {
118 message: format!("registry io error: {message}"),
119 retryable: true,
120 },
121 ResolveError::Parse(message) => Self::ResolutionFailed {
122 message: format!("parse error: {message}"),
123 retryable: false,
124 },
125 }
126 }
127}