mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 23:21:02 +00:00
Unify error enums in substrate and ethereum clients with thiserror (#1094)
* Unify error enums in substrate and ethereum clients with `thiserror` Related to https://github.com/paritytech/parity-bridges-common/issues/857 * Add license pre-amble * rustfmt * Fix spelling
This commit is contained in:
committed by
Bastian Köcher
parent
7b4f1c2236
commit
5842968273
@@ -15,6 +15,7 @@ log = "0.4.11"
|
||||
num-traits = "0.2"
|
||||
rand = "0.7"
|
||||
tokio = "1.8"
|
||||
thiserror = "1.0.26"
|
||||
|
||||
# Bridge dependencies
|
||||
|
||||
|
||||
@@ -20,78 +20,54 @@ use jsonrpsee_ws_client::types::Error as RpcError;
|
||||
use relay_utils::MaybeConnectionError;
|
||||
use sc_rpc_api::system::Health;
|
||||
use sp_runtime::transaction_validity::TransactionValidityError;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Result type used by Substrate client.
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Errors that can occur only when interacting with
|
||||
/// a Substrate node through RPC.
|
||||
#[derive(Debug)]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
/// IO error.
|
||||
Io(std::io::Error),
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
/// An error that can occur when making a request to
|
||||
/// an JSON-RPC server.
|
||||
RpcError(RpcError),
|
||||
#[error("RPC error: {0}")]
|
||||
RpcError(#[from] RpcError),
|
||||
/// The response from the server could not be SCALE decoded.
|
||||
ResponseParseFailed(codec::Error),
|
||||
#[error("Response parse failed: {0}")]
|
||||
ResponseParseFailed(#[from] codec::Error),
|
||||
/// The Substrate bridge pallet has not yet been initialized.
|
||||
#[error("The Substrate bridge pallet has not been initialized yet.")]
|
||||
UninitializedBridgePallet,
|
||||
/// Account does not exist on the chain.
|
||||
#[error("Account does not exist on the chain.")]
|
||||
AccountDoesNotExist,
|
||||
/// Runtime storage is missing mandatory ":code:" entry.
|
||||
#[error("Mandatory :code: entry is missing from runtime storage.")]
|
||||
MissingMandatoryCodeEntry,
|
||||
/// The client we're connected to is not synced, so we can't rely on its state.
|
||||
#[error("Substrate client is not synced {0}.")]
|
||||
ClientNotSynced(Health),
|
||||
/// An error has happened when we have tried to parse storage proof.
|
||||
#[error("Error when parsing storage proof: {0:?}.")]
|
||||
StorageProofError(bp_runtime::StorageProofError),
|
||||
/// The Substrate transaction is invalid.
|
||||
TransactionInvalid(TransactionValidityError),
|
||||
#[error("Substrate transaction is invalid: {0:?}")]
|
||||
TransactionInvalid(#[from] TransactionValidityError),
|
||||
/// Custom logic error.
|
||||
#[error("{0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::Io(ref e) => Some(e),
|
||||
Self::RpcError(ref e) => Some(e),
|
||||
Self::ResponseParseFailed(ref e) => Some(e),
|
||||
Self::UninitializedBridgePallet => None,
|
||||
Self::AccountDoesNotExist => None,
|
||||
Self::MissingMandatoryCodeEntry => None,
|
||||
Self::ClientNotSynced(_) => None,
|
||||
Self::StorageProofError(_) => None,
|
||||
Self::TransactionInvalid(_) => None,
|
||||
Self::Custom(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RpcError> for Error {
|
||||
fn from(error: RpcError) -> Self {
|
||||
Error::RpcError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
Error::Io(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tokio::task::JoinError> for Error {
|
||||
fn from(error: tokio::task::JoinError) -> Self {
|
||||
Error::Custom(format!("Failed to wait tokio task: {}", error))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionValidityError> for Error {
|
||||
fn from(error: TransactionValidityError) -> Self {
|
||||
Error::TransactionInvalid(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl MaybeConnectionError for Error {
|
||||
fn is_connection_error(&self) -> bool {
|
||||
matches!(
|
||||
@@ -105,30 +81,3 @@ impl MaybeConnectionError for Error {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let s = match self {
|
||||
Self::Io(e) => e.to_string(),
|
||||
Self::RpcError(e) => e.to_string(),
|
||||
Self::ResponseParseFailed(e) => e.to_string(),
|
||||
Self::UninitializedBridgePallet =>
|
||||
"The Substrate bridge pallet has not been initialized yet.".into(),
|
||||
Self::AccountDoesNotExist => "Account does not exist on the chain".into(),
|
||||
Self::MissingMandatoryCodeEntry =>
|
||||
"Mandatory :code: entry is missing from runtime storage".into(),
|
||||
Self::StorageProofError(e) => format!("Error when parsing storage proof: {:?}", e),
|
||||
Self::ClientNotSynced(health) => format!("Substrate client is not synced: {}", health),
|
||||
Self::TransactionInvalid(e) => format!("Substrate transaction is invalid: {:?}", e),
|
||||
Self::Custom(e) => e.clone(),
|
||||
};
|
||||
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for String {
|
||||
fn from(error: Error) -> String {
|
||||
error.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,23 +17,30 @@
|
||||
//! Pallet provides a set of guard functions that are running in background threads
|
||||
//! and are aborting process if some condition fails.
|
||||
|
||||
use crate::{Chain, ChainWithBalances, Client};
|
||||
use crate::{error::Error, Chain, ChainWithBalances, Client};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use num_traits::CheckedSub;
|
||||
use sp_version::RuntimeVersion;
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fmt::Display,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
/// Guards environment.
|
||||
#[async_trait]
|
||||
pub trait Environment<C: ChainWithBalances>: Send + Sync + 'static {
|
||||
/// Error type.
|
||||
type Error: Display + Send + Sync + 'static;
|
||||
|
||||
/// Return current runtime version.
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, String>;
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, Self::Error>;
|
||||
/// Return free native balance of the account on the chain.
|
||||
async fn free_native_balance(&mut self, account: C::AccountId) -> Result<C::Balance, String>;
|
||||
async fn free_native_balance(
|
||||
&mut self,
|
||||
account: C::AccountId,
|
||||
) -> Result<C::Balance, Self::Error>;
|
||||
|
||||
/// Return current time.
|
||||
fn now(&self) -> Instant {
|
||||
@@ -74,7 +81,7 @@ pub fn abort_on_spec_version_change<C: ChainWithBalances>(
|
||||
},
|
||||
Err(error) => log::warn!(
|
||||
target: "bridge-guard",
|
||||
"Failed to read {} runtime version: {:?}. Relay may need to be stopped manually",
|
||||
"Failed to read {} runtime version: {}. Relay may need to be stopped manually",
|
||||
C::NAME,
|
||||
error,
|
||||
),
|
||||
@@ -137,7 +144,7 @@ pub fn abort_when_account_balance_decreased<C: ChainWithBalances>(
|
||||
Err(error) => {
|
||||
log::warn!(
|
||||
target: "bridge-guard",
|
||||
"Failed to read {} account {:?} balance: {:?}. Relay may need to be stopped manually",
|
||||
"Failed to read {} account {:?} balance: {}. Relay may need to be stopped manually",
|
||||
C::NAME,
|
||||
account_id,
|
||||
error,
|
||||
@@ -157,12 +164,17 @@ fn conditions_check_delay<C: Chain>() -> Duration {
|
||||
|
||||
#[async_trait]
|
||||
impl<C: ChainWithBalances> Environment<C> for Client<C> {
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, String> {
|
||||
Client::<C>::runtime_version(self).await.map_err(|e| e.to_string())
|
||||
type Error = Error;
|
||||
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, Self::Error> {
|
||||
Client::<C>::runtime_version(self).await
|
||||
}
|
||||
|
||||
async fn free_native_balance(&mut self, account: C::AccountId) -> Result<C::Balance, String> {
|
||||
Client::<C>::free_native_balance(self, account).await.map_err(|e| e.to_string())
|
||||
async fn free_native_balance(
|
||||
&mut self,
|
||||
account: C::AccountId,
|
||||
) -> Result<C::Balance, Self::Error> {
|
||||
Client::<C>::free_native_balance(self, account).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,11 +232,13 @@ mod tests {
|
||||
|
||||
#[async_trait]
|
||||
impl Environment<TestChain> for TestEnvironment {
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, String> {
|
||||
type Error = Error;
|
||||
|
||||
async fn runtime_version(&mut self) -> Result<RuntimeVersion, Self::Error> {
|
||||
Ok(self.runtime_version_rx.next().await.unwrap_or_default())
|
||||
}
|
||||
|
||||
async fn free_native_balance(&mut self, _account: u32) -> Result<u32, String> {
|
||||
async fn free_native_balance(&mut self, _account: u32) -> Result<u32, Self::Error> {
|
||||
Ok(self.free_native_balance_rx.next().await.unwrap_or_default())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user