use ethers::prelude::nonce_manager::NonceManagerError;
use ethers::prelude::signer::SignerMiddlewareError;
use ethers::providers::{JsonRpcError, ProviderError};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum RpcError {
#[error("error on backend interface: {0}")]
InterfaceError(String),
#[error("error in smart contract '{0}' while executing '{1}': {2}")]
ContractError(String, String, String),
#[error("middleware error: {0}")]
MiddlewareError(String),
#[error("block with such id does not (yet) exist")]
NoSuchBlock,
#[error("filter does not contain any criteria")]
FilterIsEmpty,
#[error("transaction {0} has not been included on-chain")]
TransactionDropped(String),
#[error("transaction submission to the RPC provider timed out")]
Timeout,
#[error("non-specific RPC error occurred: {0}")]
GeneralError(String),
#[error(transparent)]
KeypairError(#[from] ethers::signers::WalletError),
#[error(transparent)]
ProviderError(#[from] ProviderError),
#[error("multicall Error: {0}")]
MulticallError(String),
#[error("conversion error: {0}")]
ConversionError(String),
}
pub type Result<T> = std::result::Result<T, RpcError>;
impl<M> From<NonceManagerError<M>> for RpcError
where
M: ethers::middleware::Middleware,
{
fn from(value: NonceManagerError<M>) -> Self {
Self::MiddlewareError(value.to_string())
}
}
impl<M, S> From<SignerMiddlewareError<M, S>> for RpcError
where
M: ethers::middleware::Middleware,
S: ethers::signers::Signer,
{
fn from(value: SignerMiddlewareError<M, S>) -> Self {
Self::MiddlewareError(value.to_string())
}
}
#[derive(Error, Clone, Debug, PartialEq)]
pub enum HttpRequestError {
#[error("connection timed out")]
Timeout,
#[error("http error - status {0}")]
HttpError(http_types::StatusCode),
#[error("io error when performing http request: {0}")]
TransportError(String),
#[error("unrecognized error: {0}")]
UnknownError(String),
}
#[derive(Error, Debug)]
pub enum JsonRpcProviderClientError {
#[error("Deserialization Error: {err}. Response: {text}")]
SerdeJson {
err: serde_json::Error,
text: String,
},
#[error(transparent)]
JsonRpcError(#[from] JsonRpcError),
#[error(transparent)]
BackendError(#[from] HttpRequestError),
}
impl From<JsonRpcProviderClientError> for ProviderError {
fn from(src: JsonRpcProviderClientError) -> Self {
match src {
JsonRpcProviderClientError::BackendError(err) => ProviderError::CustomError(err.to_string()),
_ => ProviderError::JsonRpcClientError(Box::new(src)),
}
}
}
impl ethers::providers::RpcError for JsonRpcProviderClientError {
fn as_error_response(&self) -> Option<&JsonRpcError> {
if let JsonRpcProviderClientError::JsonRpcError(err) = self {
Some(err)
} else {
None
}
}
fn as_serde_error(&self) -> Option<&serde_json::Error> {
match self {
JsonRpcProviderClientError::SerdeJson { err, .. } => Some(err),
_ => None,
}
}
}