1use crate::types::DeploymentId;
2use thiserror::Error;
3
4pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Error, Debug)]
8pub enum Error {
9 #[error("Database error: {0}")]
13 Database(#[from] sqlx::Error),
14
15 #[error("Serialization error: {0}")]
16 Serialization(#[from] serde_json::Error),
17
18 #[error("Hex decode error: {0}")]
19 HexDecode(#[from] hex::FromHexError),
20
21 #[error("Network not found: {0}")]
25 NetworkNotFound(String),
26
27 #[error("Contract not found: {0}")]
28 ContractNotFound(String),
29
30 #[error("Deployment not found: {0}")]
31 DeploymentNotFound(String),
32
33 #[error("Deployment not found by ID: {0}")]
34 DeploymentNotFoundById(DeploymentId),
35
36 #[error("Wallet not found: {0}")]
37 WalletNotFound(String),
38
39 #[error("Function '{function}' not found in contract '{contract}'")]
40 FunctionNotFound { contract: String, function: String },
41
42 #[error("Artifact not found: {0}")]
43 ArtifactNotFound(String),
44
45 #[error("ABI parse error: {0}")]
49 AbiParse(String),
50
51 #[error("ABI encoding error: {0}")]
52 AbiEncode(String),
53
54 #[error("ABI decoding error: {0}")]
55 AbiDecode(String),
56
57 #[error("RPC error: {0}")]
61 Rpc(String),
62
63 #[error("RPC error on chain {chain_id}: {message}")]
64 RpcWithChain { chain_id: u64, message: String },
65
66 #[error("Transaction failed: {0}")]
67 TransactionFailed(String),
68
69 #[error("Transaction reverted: {reason}")]
70 TransactionReverted {
71 reason: String,
72 tx_hash: Option<String>,
73 },
74
75 #[error("Invalid parameter '{name}': {reason}")]
79 InvalidParameter { name: String, reason: String },
80
81 #[error("Validation error: {0}")]
82 Validation(String),
83
84 #[error("Keyring error: {0}")]
88 Keyring(String),
89
90 #[error("Encryption error: {0}")]
91 Encryption(String),
92
93 #[error("Decryption error: {0}")]
94 Decryption(String),
95
96 #[error("File not found: {0}")]
100 FileNotFound(String),
101
102 #[error("IO error: {0}")]
103 Io(String),
104
105 #[error("Configuration error: {0}")]
109 Config(String),
110
111 #[error("Environment variable '{name}' not set")]
112 EnvVarNotSet { name: String },
113}
114
115impl Error {
116 pub fn is_not_found(&self) -> bool {
118 matches!(
119 self,
120 Error::NetworkNotFound(_)
121 | Error::ContractNotFound(_)
122 | Error::DeploymentNotFound(_)
123 | Error::DeploymentNotFoundById(_)
124 | Error::WalletNotFound(_)
125 | Error::FunctionNotFound { .. }
126 | Error::ArtifactNotFound(_)
127 | Error::FileNotFound(_)
128 )
129 }
130
131 pub fn is_database(&self) -> bool {
133 matches!(self, Error::Database(_))
134 }
135
136 pub fn is_validation(&self) -> bool {
138 matches!(self, Error::InvalidParameter { .. } | Error::Validation(_))
139 }
140
141 pub fn code(&self) -> &'static str {
143 match self {
144 Error::Database(_) => "DATABASE_ERROR",
145 Error::Serialization(_) => "SERIALIZATION_ERROR",
146 Error::HexDecode(_) => "HEX_DECODE_ERROR",
147 Error::NetworkNotFound(_) => "NETWORK_NOT_FOUND",
148 Error::ContractNotFound(_) => "CONTRACT_NOT_FOUND",
149 Error::DeploymentNotFound(_) | Error::DeploymentNotFoundById(_) => {
150 "DEPLOYMENT_NOT_FOUND"
151 }
152 Error::WalletNotFound(_) => "WALLET_NOT_FOUND",
153 Error::FunctionNotFound { .. } => "FUNCTION_NOT_FOUND",
154 Error::ArtifactNotFound(_) => "ARTIFACT_NOT_FOUND",
155 Error::AbiParse(_) => "ABI_PARSE_ERROR",
156 Error::AbiEncode(_) => "ABI_ENCODE_ERROR",
157 Error::AbiDecode(_) => "ABI_DECODE_ERROR",
158 Error::Rpc(_) | Error::RpcWithChain { .. } => "RPC_ERROR",
159 Error::TransactionFailed(_) => "TRANSACTION_FAILED",
160 Error::TransactionReverted { .. } => "TRANSACTION_REVERTED",
161 Error::InvalidParameter { .. } => "INVALID_PARAMETER",
162 Error::Validation(_) => "VALIDATION_ERROR",
163 Error::Keyring(_) => "KEYRING_ERROR",
164 Error::Encryption(_) => "ENCRYPTION_ERROR",
165 Error::Decryption(_) => "DECRYPTION_ERROR",
166 Error::FileNotFound(_) => "FILE_NOT_FOUND",
167 Error::Io(_) => "IO_ERROR",
168 Error::Config(_) => "CONFIG_ERROR",
169 Error::EnvVarNotSet { .. } => "ENV_VAR_NOT_SET",
170 }
171 }
172}
173
174impl Error {
176 pub fn function_not_found(contract: impl Into<String>, function: impl Into<String>) -> Self {
177 Error::FunctionNotFound {
178 contract: contract.into(),
179 function: function.into(),
180 }
181 }
182
183 pub fn invalid_param(name: impl Into<String>, reason: impl Into<String>) -> Self {
184 Error::InvalidParameter {
185 name: name.into(),
186 reason: reason.into(),
187 }
188 }
189
190 pub fn rpc_error(chain_id: u64, message: impl Into<String>) -> Self {
191 Error::RpcWithChain {
192 chain_id,
193 message: message.into(),
194 }
195 }
196}