openzeppelin_relayer/models/error/
relayer.rs1use crate::{
2 models::{SignerError, SignerFactoryError},
3 repositories::TransactionCounterError,
4 services::provider::{ProviderError, SolanaProviderError},
5};
6
7use super::{ApiError, RepositoryError};
8use crate::models::NetworkError;
9use serde::Serialize;
10use thiserror::Error;
11
12#[derive(Error, Debug, Serialize)]
13pub enum RelayerError {
14 #[error("Network configuration error: {0}")]
15 NetworkConfiguration(String),
16 #[error("Provider error: {0}")]
17 ProviderError(String),
18 #[error("Underlying provider error: {0}")]
19 UnderlyingProvider(#[from] ProviderError),
20 #[error("Underlying Solana provider error: {0}")]
21 UnderlyingSolanaProvider(#[from] SolanaProviderError),
22 #[error("Queue error: {0}")]
23 QueueError(String),
24 #[error("Signer factory error: {0}")]
25 SignerFactoryError(#[from] SignerFactoryError),
26 #[error("Signer error: {0}")]
27 SignerError(#[from] SignerError),
28 #[error("Not supported: {0}")]
29 NotSupported(String),
30 #[error("Relayer is disabled")]
31 RelayerDisabled,
32 #[error("Relayer is paused")]
33 RelayerPaused,
34 #[error("Transaction sequence error: {0}")]
35 TransactionSequenceError(#[from] TransactionCounterError),
36 #[error("Insufficient balance error: {0}")]
37 InsufficientBalanceError(String),
38 #[error("Insufficient relayer balance: {0}")]
39 InsufficientRelayerBalance(String),
40 #[error("Relayer Policy configuration error: {0}")]
41 PolicyConfigurationError(String),
42 #[error("Invalid Dex name : {0}")]
43 InvalidDexName(String),
44 #[error("Dex error : {0}")]
45 DexError(String),
46 #[error("Transaction validation error: {0}")]
47 ValidationError(String),
48 #[error("Internal error: {0}")]
49 Internal(String),
50}
51
52impl From<RelayerError> for ApiError {
53 fn from(error: RelayerError) -> Self {
54 match error {
55 RelayerError::NetworkConfiguration(msg) => ApiError::InternalError(msg),
56 RelayerError::ProviderError(msg) => ApiError::InternalError(msg),
57 RelayerError::QueueError(msg) => ApiError::InternalError(msg),
58 RelayerError::SignerError(err) => ApiError::InternalError(err.to_string()),
59 RelayerError::SignerFactoryError(err) => ApiError::InternalError(err.to_string()),
60 RelayerError::NotSupported(msg) => ApiError::BadRequest(msg),
61 RelayerError::RelayerDisabled => {
62 ApiError::ForbiddenError("Relayer disabled".to_string())
63 }
64 RelayerError::RelayerPaused => ApiError::ForbiddenError("Relayer paused".to_string()),
65 RelayerError::TransactionSequenceError(err) => ApiError::InternalError(err.to_string()),
66 RelayerError::InsufficientBalanceError(msg) => ApiError::BadRequest(msg),
67 RelayerError::InsufficientRelayerBalance(msg) => ApiError::BadRequest(msg),
68 RelayerError::UnderlyingProvider(err) => ApiError::InternalError(err.to_string()),
69 RelayerError::UnderlyingSolanaProvider(err) => ApiError::InternalError(err.to_string()),
70 RelayerError::PolicyConfigurationError(msg) => ApiError::InternalError(msg),
71 RelayerError::InvalidDexName(msg) => ApiError::InternalError(msg),
72 RelayerError::DexError(msg) => ApiError::InternalError(msg),
73 RelayerError::ValidationError(msg) => ApiError::BadRequest(msg),
74 RelayerError::Internal(msg) => ApiError::InternalError(msg),
75 }
76 }
77}
78
79impl From<RepositoryError> for RelayerError {
80 fn from(error: RepositoryError) -> Self {
81 RelayerError::NetworkConfiguration(error.to_string())
82 }
83}
84
85impl From<NetworkError> for RelayerError {
86 fn from(err: NetworkError) -> Self {
87 RelayerError::NetworkConfiguration(err.to_string())
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::models::SignerError;
95 use crate::repositories::TransactionCounterError;
96 use crate::services::provider::{ProviderError, SolanaProviderError};
97
98 #[test]
99 fn test_relayer_error_variants() {
100 let network_error = RelayerError::NetworkConfiguration("Invalid network".to_string());
101 assert_eq!(
102 network_error.to_string(),
103 "Network configuration error: Invalid network"
104 );
105
106 let provider_error = RelayerError::ProviderError("Connection failed".to_string());
107 assert_eq!(
108 provider_error.to_string(),
109 "Provider error: Connection failed"
110 );
111
112 let queue_error = RelayerError::QueueError("Queue full".to_string());
113 assert_eq!(queue_error.to_string(), "Queue error: Queue full");
114
115 let not_supported = RelayerError::NotSupported("Feature unavailable".to_string());
116 assert_eq!(
117 not_supported.to_string(),
118 "Not supported: Feature unavailable"
119 );
120
121 let disabled = RelayerError::RelayerDisabled;
122 assert_eq!(disabled.to_string(), "Relayer is disabled");
123
124 let paused = RelayerError::RelayerPaused;
125 assert_eq!(paused.to_string(), "Relayer is paused");
126
127 let insufficient_balance =
128 RelayerError::InsufficientBalanceError("Not enough ETH".to_string());
129 assert_eq!(
130 insufficient_balance.to_string(),
131 "Insufficient balance error: Not enough ETH"
132 );
133
134 let policy_error = RelayerError::PolicyConfigurationError("Invalid policy".to_string());
135 assert_eq!(
136 policy_error.to_string(),
137 "Relayer Policy configuration error: Invalid policy"
138 );
139 }
140
141 #[test]
142 fn test_from_provider_error() {
143 let provider_error = ProviderError::NetworkConfiguration("RPC timeout".to_string());
144 let relayer_error: RelayerError = provider_error.into();
145
146 assert!(matches!(relayer_error, RelayerError::UnderlyingProvider(_)));
147 assert!(relayer_error.to_string().contains("RPC timeout"));
148 }
149
150 #[test]
151 fn test_from_solana_provider_error() {
152 let solana_error = SolanaProviderError::RpcError("Solana RPC down".to_string());
153 let relayer_error: RelayerError = solana_error.into();
154
155 assert!(matches!(
156 relayer_error,
157 RelayerError::UnderlyingSolanaProvider(_)
158 ));
159 assert!(relayer_error.to_string().contains("Solana RPC down"));
160 }
161
162 #[test]
163 fn test_from_signer_factory_error() {
164 let factory_error = SignerFactoryError::InvalidConfig("Unknown chain".to_string());
165 let relayer_error: RelayerError = factory_error.into();
166
167 assert!(matches!(relayer_error, RelayerError::SignerFactoryError(_)));
168 assert!(relayer_error.to_string().contains("Unknown chain"));
169 }
170
171 #[test]
172 fn test_from_signer_error() {
173 let signer_error = SignerError::SigningError("Invalid key".to_string());
174 let relayer_error: RelayerError = signer_error.into();
175
176 assert!(matches!(relayer_error, RelayerError::SignerError(_)));
177 assert!(relayer_error.to_string().contains("Invalid key"));
178 }
179
180 #[test]
181 fn test_from_transaction_counter_error() {
182 let counter_error = TransactionCounterError::NotFound("Nonce not found".to_string());
183 let relayer_error: RelayerError = counter_error.into();
184
185 assert!(matches!(
186 relayer_error,
187 RelayerError::TransactionSequenceError(_)
188 ));
189 assert!(relayer_error.to_string().contains("Nonce not found"));
190 }
191
192 #[test]
193 fn test_conversion_to_api_error() {
194 let network_error = RelayerError::NetworkConfiguration("Invalid network".to_string());
195 let api_error: ApiError = network_error.into();
196 assert!(matches!(api_error, ApiError::InternalError(_)));
197
198 let not_supported = RelayerError::NotSupported("Feature unavailable".to_string());
199 let api_error: ApiError = not_supported.into();
200 assert!(matches!(api_error, ApiError::BadRequest(_)));
201
202 let disabled = RelayerError::RelayerDisabled;
203 let api_error: ApiError = disabled.into();
204 assert!(matches!(api_error, ApiError::ForbiddenError(_)));
205 assert_eq!(api_error.to_string(), "Forbidden: Relayer disabled");
206
207 let insufficient = RelayerError::InsufficientBalanceError("Not enough funds".to_string());
208 let api_error: ApiError = insufficient.into();
209 assert!(matches!(api_error, ApiError::BadRequest(_)));
210 }
211
212 #[test]
213 fn test_from_repository_error() {
214 let repo_error = RepositoryError::ConnectionError("Connection failed".to_string());
215 let relayer_error: RelayerError = repo_error.into();
216
217 assert!(matches!(
218 relayer_error,
219 RelayerError::NetworkConfiguration(_)
220 ));
221 assert!(relayer_error.to_string().contains("Connection failed"));
222 }
223}