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(
57 "After decoding the extrinsic at index {extrinsic_index}, {num_leftover_bytes} bytes were left, suggesting that decoding may have failed"
58 )]
59 LeftoverBytes {
60 extrinsic_index: usize,
62 num_leftover_bytes: usize,
64 },
65 #[error("Failed to decode extrinsic at index {extrinsic_index}: {error}")]
67 ExtrinsicDecodeError {
68 extrinsic_index: usize,
70 error: ExtrinsicDecodeError,
72 },
73}
74
75pub type ExtrinsicDecodeError = frame_decode::extrinsics::ExtrinsicDecodeError;
78
79#[derive(Clone, Debug, PartialEq, DeriveError)]
81#[non_exhaustive]
82pub enum MetadataError {
83 #[error("The DispatchError type isn't available")]
85 DispatchErrorNotFound,
86 #[error("Type with ID {0} not found")]
88 TypeNotFound(u32),
89 #[error("Pallet with index {0} not found")]
91 PalletIndexNotFound(u8),
92 #[error("Pallet with name {0} not found")]
94 PalletNameNotFound(String),
95 #[error("Variant with index {0} not found")]
97 VariantIndexNotFound(u8),
98 #[error("Constant with name {0} not found")]
100 ConstantNameNotFound(String),
101 #[error("Call with name {0} not found")]
103 CallNameNotFound(String),
104 #[error("Runtime trait with name {0} not found")]
106 RuntimeTraitNotFound(String),
107 #[error("Runtime method with name {0} not found")]
109 RuntimeMethodNotFound(String),
110 #[error("View Function with query ID {} not found", hex::encode(.0))]
112 ViewFunctionNotFound([u8; 32]),
113 #[error("Call type not found in pallet with index {0}")]
115 CallTypeNotFoundInPallet(u8),
116 #[error("Event type not found in pallet with index {0}")]
118 EventTypeNotFoundInPallet(u8),
119 #[error("Storage details not found in pallet with name {0}")]
121 StorageNotFoundInPallet(String),
122 #[error("Storage entry {0} not found")]
124 StorageEntryNotFound(String),
125 #[error("The generated code is not compatible with the node")]
127 IncompatibleCodegen,
128 #[error("Custom value with name {0} not found")]
130 CustomValueNameNotFound(String),
131}
132
133#[derive(Clone, Debug, DeriveError)]
135#[non_exhaustive]
136pub enum StorageAddressError {
137 #[error("Storage lookup requires {expected} keys but more keys have been provided.")]
139 TooManyKeys {
140 expected: usize,
142 },
143 #[error("Storage entry in metadata does not have the correct number of hashers to fields")]
145 WrongNumberOfHashers {
146 hashers: usize,
148 fields: usize,
150 },
151 #[error("Not enough remaining bytes to decode the storage address/key")]
153 NotEnoughBytes,
154 #[error("We have leftover bytes after decoding the storage address")]
156 TooManyBytes,
157 #[error(
159 "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"
160 )]
161 UnexpectedAddressBytes,
162 #[error(
164 "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"
165 )]
166 HasherCannotReconstructKey {
167 ty_id: u32,
169 hasher: StorageHasher,
171 },
172}
173
174#[derive(Debug, DeriveError)]
176#[non_exhaustive]
177pub enum ExtrinsicError {
178 #[error("Subxt does not support the extrinsic versions expected by the chain")]
180 UnsupportedVersion,
181 #[error("Cannot construct the required transaction extensions: {0}")]
183 Params(#[from] ExtrinsicParamsError),
184}
185
186impl From<ExtrinsicParamsError> for Error {
187 fn from(value: ExtrinsicParamsError) -> Self {
188 Error::Extrinsic(value.into())
189 }
190}
191
192#[derive(Debug, DeriveError)]
195#[non_exhaustive]
196pub enum ExtrinsicParamsError {
197 #[error("Cannot find type id '{type_id} in the metadata (context: {context})")]
200 MissingTypeId {
201 type_id: u32,
203 context: &'static str,
205 },
206 #[error("The chain expects a signed extension with the name {0}, but we did not provide one")]
208 UnknownTransactionExtension(String),
209 #[error("Error constructing extrinsic parameters: {0}")]
211 Custom(Box<dyn core::error::Error + Send + Sync + 'static>),
212}
213
214impl ExtrinsicParamsError {
215 pub fn custom<S: Into<String>>(error: S) -> Self {
217 let error: String = error.into();
218 let error: Box<dyn core::error::Error + Send + Sync + 'static> = Box::from(error);
219 ExtrinsicParamsError::Custom(error)
220 }
221}
222
223impl From<core::convert::Infallible> for ExtrinsicParamsError {
224 fn from(value: core::convert::Infallible) -> Self {
225 match value {}
226 }
227}