use core::fmt::Display;
use alloc::boxed::Box;
use alloc::string::String;
use subxt_metadata::StorageHasher;
#[derive(Debug)]
pub enum Error {
Codec(codec::Error),
Metadata(MetadataError),
StorageAddress(StorageAddressError),
Decode(scale_decode::Error),
Encode(scale_encode::Error),
ExtrinsicParams(ExtrinsicParamsError),
Block(BlockError),
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::Codec(e) => write!(f, "Scale codec error: {e}"),
Error::Metadata(e) => write!(f, "Metadata Error: {e}"),
Error::StorageAddress(e) => write!(f, "Storage Error: {e}"),
Error::Decode(e) => write!(f, "Error decoding into dynamic value: {e}"),
Error::Encode(e) => write!(f, "Error encoding from dynamic value: {e}"),
Error::ExtrinsicParams(e) => write!(f, "Extrinsic params error: {e}"),
Error::Block(e) => write!(f, "Error working with block_body: {}", e),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
impl_from!(ExtrinsicParamsError => Error::ExtrinsicParams);
impl_from!(BlockError => Error::Block);
impl_from!(MetadataError => Error::Metadata);
impl_from!(scale_decode::Error => Error::Decode);
impl_from!(scale_decode::visitor::DecodeError => Error::Decode);
impl_from!(scale_encode::Error => Error::Encode);
impl_from!(StorageAddressError => Error::StorageAddress);
impl_from!(codec::Error => Error::Codec);
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BlockError {
MissingType,
UnsupportedVersion(u8),
DecodingError(codec::Error),
}
impl Display for BlockError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
BlockError::MissingType => write!(f, "Extrinsic type ID cannot be resolved with the provided metadata. Make sure this is a valid metadata"),
BlockError::UnsupportedVersion(_) => write!(f, "Unsupported extrinsic version, only version 4 is supported currently"),
BlockError::DecodingError(e) => write!(f, "Cannot decode extrinsic: {e}"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for BlockError {}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum MetadataError {
DispatchErrorNotFound,
TypeNotFound(u32),
PalletIndexNotFound(u8),
PalletNameNotFound(String),
VariantIndexNotFound(u8),
ConstantNameNotFound(String),
CallNameNotFound(String),
RuntimeTraitNotFound(String),
RuntimeMethodNotFound(String),
CallTypeNotFoundInPallet(u8),
EventTypeNotFoundInPallet(u8),
StorageNotFoundInPallet(String),
StorageEntryNotFound(String),
IncompatibleCodegen,
CustomValueNameNotFound(String),
}
impl Display for MetadataError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
MetadataError::DispatchErrorNotFound => {
write!(f, "The DispatchError type isn't available")
}
MetadataError::TypeNotFound(e) => write!(f, "Type with ID {e} not found"),
MetadataError::PalletIndexNotFound(e) => write!(f, "Pallet with index {e} not found"),
MetadataError::PalletNameNotFound(e) => write!(f, "Pallet with name {e} not found"),
MetadataError::VariantIndexNotFound(e) => write!(f, "Variant with index {e} not found"),
MetadataError::ConstantNameNotFound(e) => write!(f, "Constant with name {e} not found"),
MetadataError::CallNameNotFound(e) => write!(f, "Call with name {e} not found"),
MetadataError::RuntimeTraitNotFound(e) => {
write!(f, "Runtime trait with name {e} not found")
}
MetadataError::RuntimeMethodNotFound(e) => {
write!(f, "Runtime method with name {e} not found")
}
MetadataError::CallTypeNotFoundInPallet(e) => {
write!(f, "Call type not found in pallet with index {e}")
}
MetadataError::EventTypeNotFoundInPallet(e) => {
write!(f, "Event type not found in pallet with index {e}")
}
MetadataError::StorageNotFoundInPallet(e) => {
write!(f, "Storage details not found in pallet with name {e}")
}
MetadataError::StorageEntryNotFound(e) => write!(f, "Storage entry {e} not found"),
MetadataError::IncompatibleCodegen => {
write!(f, "The generated code is not compatible with the node")
}
MetadataError::CustomValueNameNotFound(e) => {
write!(f, "Custom value with name {e} not found")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for MetadataError {}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum StorageAddressError {
TooManyKeys {
expected: usize,
},
WrongNumberOfHashers {
hashers: usize,
fields: usize,
},
NotEnoughBytes,
TooManyBytes,
UnexpectedAddressBytes,
HasherCannotReconstructKey {
ty_id: u32,
hasher: StorageHasher,
},
}
impl Display for StorageAddressError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
StorageAddressError::TooManyKeys { expected } => write!(
f,
"Storage lookup requires {expected} keys but more keys have been provided."
),
StorageAddressError::WrongNumberOfHashers { .. } => write!(
f,
"Storage entry in metadata does not have the correct number of hashers to fields"
),
StorageAddressError::NotEnoughBytes => write!(
f,
"Not enough remaining bytes to decode the storage address/key"
),
StorageAddressError::TooManyBytes => write!(
f,
"We have leftover bytes after decoding the storage address"
),
StorageAddressError::UnexpectedAddressBytes => write!(
f,
"Storage address bytes are not the expected format. Addresses need to be at least 16 bytes (pallet ++ entry) and follow a structure given by the hashers defined in the metadata"
),
StorageAddressError::HasherCannotReconstructKey { ty_id, hasher } => write!(
f,
"An invalid hasher was used to reconstruct a value with type ID {ty_id} from a hash formed by a {hasher:?} hasher. This is only possible for concat-style hashers or the identity hasher"
),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for StorageAddressError {}
#[derive(Debug)]
#[non_exhaustive]
pub enum ExtrinsicParamsError {
MissingTypeId {
type_id: u32,
context: &'static str,
},
UnknownSignedExtension(String),
Custom(Box<dyn CustomError>),
}
impl Display for ExtrinsicParamsError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
ExtrinsicParamsError::MissingTypeId { type_id, context } => write!(
f,
"Cannot find type id '{type_id} in the metadata (context: {context})"
),
ExtrinsicParamsError::UnknownSignedExtension(e) => write!(
f,
"The chain expects a signed extension with the name {e}, but we did not provide one"
),
ExtrinsicParamsError::Custom(e) => {
write!(f, "Error constructing extrinsic parameters: {e}")
}
}
}
}
#[cfg(feature = "std")]
pub trait CustomError: std::error::Error + Send + Sync + 'static {}
#[cfg(feature = "std")]
impl<T: std::error::Error + Send + Sync + 'static> CustomError for T {}
#[cfg(not(feature = "std"))]
pub trait CustomError: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static {}
#[cfg(not(feature = "std"))]
impl<T: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static> CustomError for T {}
#[cfg(feature = "std")]
impl std::error::Error for ExtrinsicParamsError {}
impl From<core::convert::Infallible> for ExtrinsicParamsError {
fn from(value: core::convert::Infallible) -> Self {
match value {}
}
}
impl From<Box<dyn CustomError>> for ExtrinsicParamsError {
fn from(value: Box<dyn CustomError>) -> Self {
ExtrinsicParamsError::Custom(value)
}
}