use alloc::boxed::Box;
use alloc::string::String;
use subxt_metadata::StorageHasher;
use thiserror::Error as DeriveError;
#[derive(Debug, DeriveError)]
pub enum Error {
#[error("Codec error: {0}")]
Codec(codec::Error),
#[error(transparent)]
Metadata(#[from] MetadataError),
#[error(transparent)]
StorageAddress(#[from] StorageAddressError),
#[error("Error decoding into dynamic value: {0}")]
Decode(#[from] scale_decode::Error),
#[error("Error encoding from dynamic value: {0}")]
Encode(#[from] scale_encode::Error),
#[error("Error constructing transaction: {0}")]
Extrinsic(#[from] ExtrinsicError),
#[error("Error working with block_body: {0}")]
Block(#[from] BlockError),
}
impl From<scale_decode::visitor::DecodeError> for Error {
fn from(err: scale_decode::visitor::DecodeError) -> Error {
Error::Decode(err.into())
}
}
impl From<codec::Error> for Error {
fn from(err: codec::Error) -> Error {
Error::Codec(err)
}
}
#[derive(Debug, DeriveError)]
pub enum BlockError {
#[error(
"After decoding the extrinsic at index {extrinsic_index}, {num_leftover_bytes} bytes were left, suggesting that decoding may have failed"
)]
LeftoverBytes {
extrinsic_index: usize,
num_leftover_bytes: usize,
},
#[error("Failed to decode extrinsic at index {extrinsic_index}: {error}")]
ExtrinsicDecodeError {
extrinsic_index: usize,
error: ExtrinsicDecodeError,
},
}
pub type ExtrinsicDecodeError = frame_decode::extrinsics::ExtrinsicDecodeError;
#[derive(Clone, Debug, PartialEq, DeriveError)]
#[non_exhaustive]
pub enum MetadataError {
#[error("The DispatchError type isn't available")]
DispatchErrorNotFound,
#[error("Type with ID {0} not found")]
TypeNotFound(u32),
#[error("Pallet with index {0} not found")]
PalletIndexNotFound(u8),
#[error("Pallet with name {0} not found")]
PalletNameNotFound(String),
#[error("Variant with index {0} not found")]
VariantIndexNotFound(u8),
#[error("Constant with name {0} not found")]
ConstantNameNotFound(String),
#[error("Call with name {0} not found")]
CallNameNotFound(String),
#[error("Runtime trait with name {0} not found")]
RuntimeTraitNotFound(String),
#[error("Runtime method with name {0} not found")]
RuntimeMethodNotFound(String),
#[error("View Function with query ID {} not found", hex::encode(.0))]
ViewFunctionNotFound([u8; 32]),
#[error("Call type not found in pallet with index {0}")]
CallTypeNotFoundInPallet(u8),
#[error("Event type not found in pallet with index {0}")]
EventTypeNotFoundInPallet(u8),
#[error("Storage details not found in pallet with name {0}")]
StorageNotFoundInPallet(String),
#[error("Storage entry {0} not found")]
StorageEntryNotFound(String),
#[error("The generated code is not compatible with the node")]
IncompatibleCodegen,
#[error("Custom value with name {0} not found")]
CustomValueNameNotFound(String),
}
#[derive(Clone, Debug, DeriveError)]
#[non_exhaustive]
pub enum StorageAddressError {
#[error("Storage lookup requires {expected} keys but more keys have been provided.")]
TooManyKeys {
expected: usize,
},
#[error("Storage entry in metadata does not have the correct number of hashers to fields")]
WrongNumberOfHashers {
hashers: usize,
fields: usize,
},
#[error("Not enough remaining bytes to decode the storage address/key")]
NotEnoughBytes,
#[error("We have leftover bytes after decoding the storage address")]
TooManyBytes,
#[error(
"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"
)]
UnexpectedAddressBytes,
#[error(
"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"
)]
HasherCannotReconstructKey {
ty_id: u32,
hasher: StorageHasher,
},
}
#[derive(Debug, DeriveError)]
#[non_exhaustive]
pub enum ExtrinsicError {
#[error("Subxt does not support the extrinsic versions expected by the chain")]
UnsupportedVersion,
#[error("Cannot construct the required transaction extensions: {0}")]
Params(#[from] ExtrinsicParamsError),
}
impl From<ExtrinsicParamsError> for Error {
fn from(value: ExtrinsicParamsError) -> Self {
Error::Extrinsic(value.into())
}
}
#[derive(Debug, DeriveError)]
#[non_exhaustive]
pub enum ExtrinsicParamsError {
#[error("Cannot find type id '{type_id} in the metadata (context: {context})")]
MissingTypeId {
type_id: u32,
context: &'static str,
},
#[error("The chain expects a signed extension with the name {0}, but we did not provide one")]
UnknownTransactionExtension(String),
#[error("Error constructing extrinsic parameters: {0}")]
Custom(Box<dyn core::error::Error + Send + Sync + 'static>),
}
impl ExtrinsicParamsError {
pub fn custom<S: Into<String>>(error: S) -> Self {
let error: String = error.into();
let error: Box<dyn core::error::Error + Send + Sync + 'static> = Box::from(error);
ExtrinsicParamsError::Custom(error)
}
}
impl From<core::convert::Infallible> for ExtrinsicParamsError {
fn from(value: core::convert::Infallible) -> Self {
match value {}
}
}