use jsonrpsee::{
client::RequestError,
transport::ws::WsNewDnsError,
};
use sp_core::crypto::SecretStringError;
use sp_runtime::{
transaction_validity::TransactionValidityError,
DispatchError,
};
use thiserror::Error;
use crate::metadata::{
Metadata,
MetadataError,
};
#[derive(Debug, Error)]
pub enum Error {
#[error("Io error: {0}")]
Io(#[from] std::io::Error),
#[error("Scale codec error: {0}")]
Codec(#[from] codec::Error),
#[error("Rpc error: {0}")]
Rpc(#[from] RequestError),
#[error("Rpc error: {0}")]
WsHandshake(#[from] WsNewDnsError),
#[error("Serde json error: {0}")]
Serialization(#[from] serde_json::error::Error),
#[error("Secret String Error")]
SecretString(SecretStringError),
#[error("Transaction Validity Error: {0:?}")]
Invalid(TransactionValidityError),
#[error("Metadata error: {0}")]
Metadata(#[from] MetadataError),
#[error("Type size unavailable while decoding event: {0:?}")]
TypeSizeUnavailable(String),
#[error("Runtime error: {0}")]
Runtime(#[from] RuntimeError),
#[error("Other error: {0}")]
Other(String),
}
impl From<SecretStringError> for Error {
fn from(error: SecretStringError) -> Self {
Error::SecretString(error)
}
}
impl From<TransactionValidityError> for Error {
fn from(error: TransactionValidityError) -> Self {
Error::Invalid(error)
}
}
impl From<&str> for Error {
fn from(error: &str) -> Self {
Error::Other(error.into())
}
}
impl From<String> for Error {
fn from(error: String) -> Self {
Error::Other(error)
}
}
#[derive(Clone, Debug, Eq, Error, PartialEq)]
pub enum RuntimeError {
#[error("Runtime module error: {0}")]
Module(ModuleError),
#[error("Bad origin: throw by ensure_signed, ensure_root or ensure_none.")]
BadOrigin,
#[error("Cannot lookup some information required to validate the transaction.")]
CannotLookup,
#[error("Other error: {0}")]
Other(String),
}
impl RuntimeError {
pub fn from_dispatch(
metadata: &Metadata,
error: DispatchError,
) -> Result<Self, Error> {
match error {
DispatchError::Module {
index,
error,
message: _,
} => {
let module = metadata.module_with_errors(index)?;
let error = module.error(error)?;
Ok(Self::Module(ModuleError {
module: module.name().to_string(),
error: error.to_string(),
}))
}
DispatchError::BadOrigin => Ok(Self::BadOrigin),
DispatchError::CannotLookup => Ok(Self::CannotLookup),
DispatchError::Other(msg) => Ok(Self::Other(msg.into())),
}
}
}
#[derive(Clone, Debug, Eq, Error, PartialEq)]
#[error("{error} from {module}")]
pub struct ModuleError {
pub module: String,
pub error: String,
}