use std::borrow::Borrow;
pub use crate::tx_status::{TxError, TxStatusExt, TxSuccess};
use gear_core::ids::ActorId;
use subxt::{
error::DispatchError,
ext::{scale_encode, subxt_rpcs},
};
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error, derive_more::Unwrap)]
pub enum Error {
#[error("the queried event not found")]
EventNotFound,
#[error("the queried storage entry not found")]
StorageEntryNotFound,
#[error("subscription has been died")]
SubscriptionDied,
#[error("program has been terminated")]
ProgramTerminated,
#[error("{0} is invalid")]
InvalidPage(FailedPage),
#[error("{0} was not found in the storage")]
PageNotFound(FailedPage),
#[error(transparent)]
Tx(#[from] TxError),
#[error("failed to parse URL: {0}")]
InvalidUrl(#[from] url::ParseError),
#[error(transparent)]
ClientError(#[from] jsonrpsee::core::ClientError),
#[error(transparent)]
Subxt(Box<subxt::Error>),
#[error(transparent)]
Codec(#[from] subxt::ext::codec::Error),
#[error(transparent)]
SubxtRpc(#[from] subxt_rpcs::Error),
#[error(transparent)]
SecretString(#[from] sp_core::crypto::SecretStringError),
#[error(transparent)]
ScaleEncode(#[from] scale_encode::Error),
#[error(transparent)]
Crypto(#[from] sp_core::crypto::PublicError),
#[error(transparent)]
Metadata(#[from] subxt::error::MetadataError),
#[error("runtime error: {0:?}")]
Runtime(crate::RuntimeError),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::Display)]
#[display("Page {index} of Program {program}")]
pub struct FailedPage {
pub index: u32,
pub program: ActorId,
}
impl FailedPage {
pub fn new(index: u32, program: ActorId) -> Self {
Self { index, program }
}
pub fn invalid(self) -> Error {
Error::InvalidPage(self)
}
pub fn not_found(self) -> Error {
Error::PageNotFound(self)
}
}
impl From<crate::RuntimeError> for Error {
fn from(error: crate::RuntimeError) -> Self {
Self::Runtime(error)
}
}
fn from_subxt_error<E: Borrow<subxt::Error> + Into<Box<subxt::Error>>>(error: E) -> Error {
if let subxt::Error::Runtime(DispatchError::Module(err)) = error.borrow()
&& let Ok(runtime_error) = err.as_root_error()
{
Error::Runtime(runtime_error)
} else {
Error::Subxt(error.into())
}
}
impl From<Box<subxt::Error>> for Error {
fn from(error: Box<subxt::Error>) -> Self {
from_subxt_error(error)
}
}
impl From<subxt::Error> for Error {
fn from(error: subxt::Error) -> Self {
from_subxt_error(error)
}
}