1use alloc::boxed::Box;
8use alloc::string::String;
9use subxt_metadata::StorageHasher;
10use thiserror::Error as DeriveError;
11
12#[derive(Debug, DeriveError)]
14pub enum Error {
15 #[error("Codec error: {0}")]
17 Codec(codec::Error),
18 #[error(transparent)]
20 Metadata(#[from] MetadataError),
21 #[error(transparent)]
23 StorageAddress(#[from] StorageAddressError),
24 #[error("Error decoding into dynamic value: {0}")]
26 Decode(#[from] scale_decode::Error),
27 #[error("Error encoding from dynamic value: {0}")]
29 Encode(#[from] scale_encode::Error),
30 #[error("Error constructing transaction: {0}")]
32 Extrinsic(#[from] ExtrinsicError),
33 #[error("Error working with block_body: {0}")]
35 Block(#[from] BlockError),
36}
37
38impl From<scale_decode::visitor::DecodeError> for Error {
39 fn from(err: scale_decode::visitor::DecodeError) -> Error {
40 Error::Decode(err.into())
41 }
42}
43
44impl From<codec::Error> for Error {
47 fn from(err: codec::Error) -> Error {
48 Error::Codec(err)
49 }
50}
51
52#[derive(Debug, DeriveError)]
54pub enum BlockError {
55 #[error("After decoding the extrinsic at index {extrinsic_index}, {num_leftover_bytes} bytes were left, suggesting that decoding may have failed")]
57 LeftoverBytes {
58 extrinsic_index: usize,
60 num_leftover_bytes: usize,
62 },
63 #[error("Failed to decode extrinsic at index {extrinsic_index}: {error}")]
65 ExtrinsicDecodeError {
66 extrinsic_index: usize,
68 error: ExtrinsicDecodeError,
70 },
71}
72
73pub type ExtrinsicDecodeError = frame_decode::extrinsics::ExtrinsicDecodeError;
76
77#[derive(Clone, Debug, PartialEq, DeriveError)]
79#[non_exhaustive]
80pub enum MetadataError {
81 #[error("The DispatchError type isn't available")]
83 DispatchErrorNotFound,
84 #[error("Type with ID {0} not found")]
86 TypeNotFound(u32),
87 #[error("Pallet with index {0} not found")]
89 PalletIndexNotFound(u8),
90 #[error("Pallet with name {0} not found")]
92 PalletNameNotFound(String),
93 #[error("Variant with index {0} not found")]
95 VariantIndexNotFound(u8),
96 #[error("Constant with name {0} not found")]
98 ConstantNameNotFound(String),
99 #[error("Call with name {0} not found")]
101 CallNameNotFound(String),
102 #[error("Runtime trait with name {0} not found")]
104 RuntimeTraitNotFound(String),
105 #[error("Runtime method with name {0} not found")]
107 RuntimeMethodNotFound(String),
108 #[error("Call type not found in pallet with index {0}")]
110 CallTypeNotFoundInPallet(u8),
111 #[error("Event type not found in pallet with index {0}")]
113 EventTypeNotFoundInPallet(u8),
114 #[error("Storage details not found in pallet with name {0}")]
116 StorageNotFoundInPallet(String),
117 #[error("Storage entry {0} not found")]
119 StorageEntryNotFound(String),
120 #[error("The generated code is not compatible with the node")]
122 IncompatibleCodegen,
123 #[error("Custom value with name {0} not found")]
125 CustomValueNameNotFound(String),
126}
127
128#[derive(Clone, Debug, DeriveError)]
130#[non_exhaustive]
131pub enum StorageAddressError {
132 #[error("Storage lookup requires {expected} keys but more keys have been provided.")]
134 TooManyKeys {
135 expected: usize,
137 },
138 #[error("Storage entry in metadata does not have the correct number of hashers to fields")]
140 WrongNumberOfHashers {
141 hashers: usize,
143 fields: usize,
145 },
146 #[error("Not enough remaining bytes to decode the storage address/key")]
148 NotEnoughBytes,
149 #[error("We have leftover bytes after decoding the storage address")]
151 TooManyBytes,
152 #[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")]
154 UnexpectedAddressBytes,
155 #[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")]
157 HasherCannotReconstructKey {
158 ty_id: u32,
160 hasher: StorageHasher,
162 },
163}
164
165#[derive(Debug, DeriveError)]
167#[non_exhaustive]
168pub enum ExtrinsicError {
169 #[error("Subxt does not support the extrinsic versions expected by the chain")]
171 UnsupportedVersion,
172 #[error("Cannot construct the required transaction extensions: {0}")]
174 Params(#[from] ExtrinsicParamsError),
175}
176
177impl From<ExtrinsicParamsError> for Error {
178 fn from(value: ExtrinsicParamsError) -> Self {
179 Error::Extrinsic(value.into())
180 }
181}
182
183#[derive(Debug, DeriveError)]
186#[non_exhaustive]
187pub enum ExtrinsicParamsError {
188 #[error("Cannot find type id '{type_id} in the metadata (context: {context})")]
191 MissingTypeId {
192 type_id: u32,
194 context: &'static str,
196 },
197 #[error("The chain expects a signed extension with the name {0}, but we did not provide one")]
199 UnknownTransactionExtension(String),
200 #[error("Error constructing extrinsic parameters: {0}")]
202 Custom(Box<dyn CustomError>),
203}
204
205#[cfg(feature = "std")]
207pub trait CustomError: std::error::Error + Send + Sync + 'static {}
208#[cfg(feature = "std")]
209impl<T: std::error::Error + Send + Sync + 'static> CustomError for T {}
210
211#[cfg(not(feature = "std"))]
213pub trait CustomError: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static {}
214#[cfg(not(feature = "std"))]
215impl<T: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static> CustomError for T {}
216
217impl From<core::convert::Infallible> for ExtrinsicParamsError {
218 fn from(value: core::convert::Infallible) -> Self {
219 match value {}
220 }
221}
222
223impl From<Box<dyn CustomError>> for ExtrinsicParamsError {
224 fn from(value: Box<dyn CustomError>) -> Self {
225 ExtrinsicParamsError::Custom(value)
226 }
227}