1mod dispatch_error;
8mod hex;
9
10crate::macros::cfg_unstable_light_client! {
11 pub use pezkuwi_subxt_lightclient::LightClientError;
12}
13
14pub use dispatch_error::{
16 ArithmeticError, DispatchError, ModuleError, TokenError, TransactionalError,
17};
18
19pub use crate::Metadata;
21pub use hex::Hex;
22pub use pezkuwi_subxt_metadata::TryFromError as MetadataTryFromError;
23pub use scale_decode::Error as DecodeError;
24pub use scale_encode::Error as EncodeError;
25
26pub use pezkuwi_subxt_core::error::{
28 ConstantError,
29 CustomValueError,
30 EventsError as CoreEventsError,
31 ExtrinsicDecodeErrorAt,
33 ExtrinsicError as CoreExtrinsicError,
35 RuntimeApiError as CoreRuntimeApiError,
36 StorageError as CoreStorageError,
37 StorageKeyError,
38 StorageValueError,
39 ViewFunctionError as CoreViewFunctionError,
40};
41
42#[derive(Debug, thiserror::Error)]
45#[non_exhaustive]
46#[allow(missing_docs)]
47pub enum Error {
48 #[error(transparent)]
49 ExtrinsicDecodeErrorAt(#[from] ExtrinsicDecodeErrorAt),
50 #[error(transparent)]
51 ConstantError(#[from] ConstantError),
52 #[error(transparent)]
53 CustomValueError(#[from] CustomValueError),
54 #[error(transparent)]
55 StorageKeyError(#[from] StorageKeyError),
56 #[error(transparent)]
57 StorageValueError(#[from] StorageValueError),
58 #[error(transparent)]
59 BackendError(#[from] BackendError),
60 #[error(transparent)]
61 BlockError(#[from] BlockError),
62 #[error(transparent)]
63 AccountNonceError(#[from] AccountNonceError),
64 #[error(transparent)]
65 OnlineClientError(#[from] OnlineClientError),
66 #[error(transparent)]
67 RuntimeUpdaterError(#[from] RuntimeUpdaterError),
68 #[error(transparent)]
69 RuntimeUpdateeApplyError(#[from] RuntimeUpdateeApplyError),
70 #[error(transparent)]
71 RuntimeApiError(#[from] RuntimeApiError),
72 #[error(transparent)]
73 EventsError(#[from] EventsError),
74 #[error(transparent)]
75 ExtrinsicError(#[from] ExtrinsicError),
76 #[error(transparent)]
77 ViewFunctionError(#[from] ViewFunctionError),
78 #[error(transparent)]
79 TransactionProgressError(#[from] TransactionProgressError),
80 #[error(transparent)]
81 TransactionStatusError(#[from] TransactionStatusError),
82 #[error(transparent)]
83 TransactionEventsError(#[from] TransactionEventsError),
84 #[error(transparent)]
85 TransactionFinalizedSuccessError(#[from] TransactionFinalizedSuccessError),
86 #[error(transparent)]
87 ModuleErrorDetailsError(#[from] ModuleErrorDetailsError),
88 #[error(transparent)]
89 ModuleErrorDecodeError(#[from] ModuleErrorDecodeError),
90 #[error(transparent)]
91 DispatchErrorDecodeError(#[from] DispatchErrorDecodeError),
92 #[error(transparent)]
93 StorageError(#[from] StorageError),
94 #[error("Other RPC client error: {0}")]
98 OtherRpcClientError(#[from] pezkuwi_subxt_rpcs::Error),
99 #[error("Other codec error: {0}")]
100 OtherCodecError(#[from] codec::Error),
101 #[cfg(feature = "unstable-light-client")]
102 #[error("Other light client error: {0}")]
103 OtherLightClientError(#[from] pezkuwi_subxt_lightclient::LightClientError),
104 #[cfg(feature = "unstable-light-client")]
105 #[error("Other light client RPC error: {0}")]
106 OtherLightClientRpcError(#[from] pezkuwi_subxt_lightclient::LightClientRpcError),
107 #[error("Other error: {0}")]
111 Other(Box<dyn std::error::Error + Send + Sync + 'static>),
112}
113
114impl From<std::convert::Infallible> for Error {
115 fn from(value: std::convert::Infallible) -> Self {
116 match value {}
117 }
118}
119
120impl Error {
121 pub fn other<E: std::error::Error + Send + Sync + 'static>(error: E) -> Error {
124 Error::Other(Box::new(error))
125 }
126
127 pub fn other_str(error: impl Into<String>) -> Error {
130 #[derive(thiserror::Error, Debug, Clone)]
131 #[error("{0}")]
132 struct StrError(String);
133 Error::Other(Box::new(StrError(error.into())))
134 }
135
136 pub fn is_disconnected_will_reconnect(&self) -> bool {
138 matches!(
139 self.backend_error(),
140 Some(BackendError::Rpc(RpcError::ClientError(
141 pezkuwi_subxt_rpcs::Error::DisconnectedWillReconnect(_)
142 )))
143 )
144 }
145
146 pub fn is_rpc_limit_reached(&self) -> bool {
148 matches!(self.backend_error(), Some(BackendError::Rpc(RpcError::LimitReached)))
149 }
150
151 fn backend_error(&self) -> Option<&BackendError> {
152 match self {
153 Error::BlockError(e) => e.backend_error(),
154 Error::AccountNonceError(e) => e.backend_error(),
155 Error::OnlineClientError(e) => e.backend_error(),
156 Error::RuntimeUpdaterError(e) => e.backend_error(),
157 Error::RuntimeApiError(e) => e.backend_error(),
158 Error::EventsError(e) => e.backend_error(),
159 Error::ExtrinsicError(e) => e.backend_error(),
160 Error::ViewFunctionError(e) => e.backend_error(),
161 Error::TransactionProgressError(e) => e.backend_error(),
162 Error::TransactionEventsError(e) => e.backend_error(),
163 Error::TransactionFinalizedSuccessError(e) => e.backend_error(),
164 Error::StorageError(e) => e.backend_error(),
165 _ => None,
167 }
168 }
169}
170
171#[derive(Debug, thiserror::Error)]
172#[non_exhaustive]
173#[allow(missing_docs)]
174pub enum BackendError {
175 #[error("Backend error: RPC error: {0}")]
176 Rpc(#[from] RpcError),
177 #[error("Backend error: Could not find metadata version {0}")]
178 MetadataVersionNotFound(u32),
179 #[error("Backend error: Could not codec::Decode Runtime API response: {0}")]
180 CouldNotScaleDecodeRuntimeResponse(codec::Error),
181 #[error(
182 "Backend error: Could not codec::Decode metadata bytes into pezkuwi_subxt::Metadata: {0}"
183 )]
184 CouldNotDecodeMetadata(codec::Error),
185 #[error("Custom backend error: {0}")]
188 Other(String),
189}
190
191impl BackendError {
192 pub fn is_disconnected_will_reconnect(&self) -> bool {
194 matches!(
195 self,
196 BackendError::Rpc(RpcError::ClientError(
197 pezkuwi_subxt_rpcs::Error::DisconnectedWillReconnect(_)
198 ))
199 )
200 }
201
202 pub fn is_rpc_limit_reached(&self) -> bool {
204 matches!(self, BackendError::Rpc(RpcError::LimitReached))
205 }
206}
207
208impl From<pezkuwi_subxt_rpcs::Error> for BackendError {
209 fn from(value: pezkuwi_subxt_rpcs::Error) -> Self {
210 BackendError::Rpc(RpcError::ClientError(value))
211 }
212}
213
214#[derive(Debug, thiserror::Error)]
217#[non_exhaustive]
218pub enum RpcError {
219 #[error("RPC error: {0}")]
221 ClientError(#[from] pezkuwi_subxt_rpcs::Error),
222 #[error("RPC error: limit reached")]
226 LimitReached,
227 #[error("RPC error: subscription dropped.")]
229 SubscriptionDropped,
230}
231
232#[derive(Debug, thiserror::Error)]
234#[non_exhaustive]
235#[allow(missing_docs)]
236pub enum BlockError {
237 #[error(
238 "Could not find the block body with hash {block_hash} (perhaps it was on a non-finalized fork?)"
239 )]
240 BlockNotFound { block_hash: Hex },
241 #[error("Could not download the block header with hash {block_hash}: {reason}")]
242 CouldNotGetBlockHeader { block_hash: Hex, reason: BackendError },
243 #[error("Could not download the latest block header: {0}")]
244 CouldNotGetLatestBlock(BackendError),
245 #[error("Could not subscribe to all blocks: {0}")]
246 CouldNotSubscribeToAllBlocks(BackendError),
247 #[error("Could not subscribe to best blocks: {0}")]
248 CouldNotSubscribeToBestBlocks(BackendError),
249 #[error("Could not subscribe to finalized blocks: {0}")]
250 CouldNotSubscribeToFinalizedBlocks(BackendError),
251 #[error("Error getting account nonce at block {block_hash}")]
252 AccountNonceError { block_hash: Hex, account_id: Hex, reason: AccountNonceError },
253}
254
255impl BlockError {
256 fn backend_error(&self) -> Option<&BackendError> {
257 match self {
258 BlockError::CouldNotGetBlockHeader { reason: e, .. }
259 | BlockError::CouldNotGetLatestBlock(e)
260 | BlockError::CouldNotSubscribeToAllBlocks(e)
261 | BlockError::CouldNotSubscribeToBestBlocks(e)
262 | BlockError::CouldNotSubscribeToFinalizedBlocks(e) => Some(e),
263 _ => None,
264 }
265 }
266}
267
268#[derive(Debug, thiserror::Error)]
269#[non_exhaustive]
270#[allow(missing_docs)]
271pub enum AccountNonceError {
272 #[error("Could not retrieve account nonce: {0}")]
273 CouldNotRetrieve(#[from] BackendError),
274 #[error("Could not decode account nonce: {0}")]
275 CouldNotDecode(#[from] codec::Error),
276 #[error("Wrong number of account nonce bytes returned: {0} (expected 2, 4 or 8)")]
277 WrongNumberOfBytes(usize),
278}
279
280impl AccountNonceError {
281 fn backend_error(&self) -> Option<&BackendError> {
282 match self {
283 AccountNonceError::CouldNotRetrieve(e) => Some(e),
284 _ => None,
285 }
286 }
287}
288
289#[derive(Debug, thiserror::Error)]
290#[non_exhaustive]
291#[allow(missing_docs)]
292pub enum OnlineClientError {
293 #[error("Cannot construct OnlineClient: {0}")]
294 RpcError(#[from] pezkuwi_subxt_rpcs::Error),
295 #[error(
296 "Cannot construct OnlineClient: Cannot fetch latest finalized block to obtain init details from: {0}"
297 )]
298 CannotGetLatestFinalizedBlock(BackendError),
299 #[error("Cannot construct OnlineClient: Cannot fetch genesis hash: {0}")]
300 CannotGetGenesisHash(BackendError),
301 #[error("Cannot construct OnlineClient: Cannot fetch current runtime version: {0}")]
302 CannotGetCurrentRuntimeVersion(BackendError),
303 #[error("Cannot construct OnlineClient: Cannot fetch metadata: {0}")]
304 CannotFetchMetadata(BackendError),
305}
306
307impl OnlineClientError {
308 fn backend_error(&self) -> Option<&BackendError> {
309 match self {
310 OnlineClientError::CannotGetLatestFinalizedBlock(e)
311 | OnlineClientError::CannotGetGenesisHash(e)
312 | OnlineClientError::CannotGetCurrentRuntimeVersion(e)
313 | OnlineClientError::CannotFetchMetadata(e) => Some(e),
314 _ => None,
315 }
316 }
317}
318
319#[derive(Debug, thiserror::Error)]
320#[non_exhaustive]
321#[allow(missing_docs)]
322pub enum RuntimeUpdaterError {
323 #[error("Error subscribing to runtime updates: The update stream ended unexpectedly")]
324 UnexpectedEndOfUpdateStream,
325 #[error("Error subscribing to runtime updates: The finalized block stream ended unexpectedly")]
326 UnexpectedEndOfBlockStream,
327 #[error("Error subscribing to runtime updates: Can't stream runtime version: {0}")]
328 CannotStreamRuntimeVersion(BackendError),
329 #[error("Error subscribing to runtime updates: Can't get next runtime version in stream: {0}")]
330 CannotGetNextRuntimeVersion(BackendError),
331 #[error("Error subscribing to runtime updates: Cannot stream finalized blocks: {0}")]
332 CannotStreamFinalizedBlocks(BackendError),
333 #[error(
334 "Error subscribing to runtime updates: Cannot get next finalized block in stream: {0}"
335 )]
336 CannotGetNextFinalizedBlock(BackendError),
337 #[error("Cannot fetch new metadata for runtime update: {0}")]
338 CannotFetchNewMetadata(BackendError),
339 #[error(
340 "Error subscribing to runtime updates: Cannot find the System.LastRuntimeUpgrade storage entry"
341 )]
342 CantFindSystemLastRuntimeUpgrade,
343 #[error("Error subscribing to runtime updates: Cannot fetch last runtime upgrade: {0}")]
344 CantFetchLastRuntimeUpgrade(StorageError),
345 #[error("Error subscribing to runtime updates: Cannot decode last runtime upgrade: {0}")]
346 CannotDecodeLastRuntimeUpgrade(StorageValueError),
347}
348
349impl RuntimeUpdaterError {
350 fn backend_error(&self) -> Option<&BackendError> {
351 match self {
352 RuntimeUpdaterError::CannotStreamRuntimeVersion(e)
353 | RuntimeUpdaterError::CannotGetNextRuntimeVersion(e)
354 | RuntimeUpdaterError::CannotStreamFinalizedBlocks(e)
355 | RuntimeUpdaterError::CannotGetNextFinalizedBlock(e)
356 | RuntimeUpdaterError::CannotFetchNewMetadata(e) => Some(e),
357 _ => None,
358 }
359 }
360}
361
362#[non_exhaustive]
364#[derive(Debug, thiserror::Error)]
365#[allow(missing_docs)]
366pub enum RuntimeUpdateeApplyError {
367 #[error("The proposed runtime update is the same as the current version")]
368 SameVersion,
369}
370
371#[non_exhaustive]
373#[derive(Debug, thiserror::Error)]
374#[allow(missing_docs)]
375pub enum RuntimeApiError {
376 #[error(
377 "Cannot access Runtime APIs at latest block: Cannot fetch latest finalized block: {0}"
378 )]
379 CannotGetLatestFinalizedBlock(BackendError),
380 #[error("{0}")]
381 OfflineError(#[from] CoreRuntimeApiError),
382 #[error("Cannot call the Runtime API: {0}")]
383 CannotCallApi(BackendError),
384}
385
386impl RuntimeApiError {
387 fn backend_error(&self) -> Option<&BackendError> {
388 match self {
389 RuntimeApiError::CannotGetLatestFinalizedBlock(e)
390 | RuntimeApiError::CannotCallApi(e) => Some(e),
391 _ => None,
392 }
393 }
394}
395
396#[non_exhaustive]
398#[derive(Debug, thiserror::Error)]
399#[allow(missing_docs)]
400pub enum EventsError {
401 #[error("{0}")]
402 OfflineError(#[from] CoreEventsError),
403 #[error("Cannot access events at latest block: Cannot fetch latest finalized block: {0}")]
404 CannotGetLatestFinalizedBlock(BackendError),
405 #[error("Cannot fetch event bytes: {0}")]
406 CannotFetchEventBytes(BackendError),
407}
408
409impl EventsError {
410 fn backend_error(&self) -> Option<&BackendError> {
411 match self {
412 EventsError::CannotGetLatestFinalizedBlock(e)
413 | EventsError::CannotFetchEventBytes(e) => Some(e),
414 _ => None,
415 }
416 }
417}
418
419#[non_exhaustive]
421#[derive(Debug, thiserror::Error)]
422#[allow(missing_docs)]
423pub enum ExtrinsicError {
424 #[error("{0}")]
425 OfflineError(#[from] CoreExtrinsicError),
426 #[error("Could not download block body to extract extrinsics from: {0}")]
427 CannotGetBlockBody(BackendError),
428 #[error("Block not found: {0}")]
429 BlockNotFound(Hex),
430 #[error("{0}")]
431 CouldNotDecodeExtrinsics(#[from] ExtrinsicDecodeErrorAt),
432 #[error(
433 "Extrinsic submission error: Cannot get latest finalized block to grab account nonce at: {0}"
434 )]
435 CannotGetLatestFinalizedBlock(BackendError),
436 #[error("Cannot find block header for block {block_hash}")]
437 CannotFindBlockHeader { block_hash: Hex },
438 #[error("Error getting account nonce at block {block_hash}")]
439 AccountNonceError { block_hash: Hex, account_id: Hex, reason: AccountNonceError },
440 #[error("Cannot submit extrinsic: {0}")]
441 ErrorSubmittingTransaction(BackendError),
442 #[error("A transaction status error was returned while submitting the extrinsic: {0}")]
443 TransactionStatusError(TransactionStatusError),
444 #[error(
445 "The transaction status stream encountered an error while submitting the extrinsic: {0}"
446 )]
447 TransactionStatusStreamError(BackendError),
448 #[error(
449 "The transaction status stream unexpectedly ended, so we don't know the status of the submitted extrinsic"
450 )]
451 UnexpectedEndOfTransactionStatusStream,
452 #[error("Cannot get fee info from Runtime API: {0}")]
453 CannotGetFeeInfo(BackendError),
454 #[error("Cannot get validation info from Runtime API: {0}")]
455 CannotGetValidationInfo(BackendError),
456 #[error("Cannot decode ValidationResult bytes: {0}")]
457 CannotDecodeValidationResult(codec::Error),
458 #[error("ValidationResult bytes could not be decoded")]
459 UnexpectedValidationResultBytes(Vec<u8>),
460}
461
462impl ExtrinsicError {
463 fn backend_error(&self) -> Option<&BackendError> {
464 match self {
465 ExtrinsicError::CannotGetBlockBody(e)
466 | ExtrinsicError::CannotGetLatestFinalizedBlock(e)
467 | ExtrinsicError::ErrorSubmittingTransaction(e)
468 | ExtrinsicError::TransactionStatusStreamError(e)
469 | ExtrinsicError::CannotGetFeeInfo(e)
470 | ExtrinsicError::CannotGetValidationInfo(e) => Some(e),
471 ExtrinsicError::AccountNonceError { reason, .. } => reason.backend_error(),
472 _ => None,
473 }
474 }
475}
476
477#[non_exhaustive]
479#[derive(Debug, thiserror::Error)]
480#[allow(missing_docs)]
481pub enum ViewFunctionError {
482 #[error("{0}")]
483 OfflineError(#[from] CoreViewFunctionError),
484 #[error(
485 "Cannot access View Functions at latest block: Cannot fetch latest finalized block: {0}"
486 )]
487 CannotGetLatestFinalizedBlock(BackendError),
488 #[error("Cannot call the View Function Runtime API: {0}")]
489 CannotCallApi(BackendError),
490}
491
492impl ViewFunctionError {
493 fn backend_error(&self) -> Option<&BackendError> {
494 match self {
495 ViewFunctionError::CannotGetLatestFinalizedBlock(e)
496 | ViewFunctionError::CannotCallApi(e) => Some(e),
497 _ => None,
498 }
499 }
500}
501
502#[non_exhaustive]
504#[derive(Debug, thiserror::Error)]
505#[allow(missing_docs)]
506pub enum TransactionProgressError {
507 #[error("Cannot get the next transaction progress update: {0}")]
508 CannotGetNextProgressUpdate(BackendError),
509 #[error("Error during transaction progress: {0}")]
510 TransactionStatusError(#[from] TransactionStatusError),
511 #[error(
512 "The transaction status stream unexpectedly ended, so we have no further transaction progress updates"
513 )]
514 UnexpectedEndOfTransactionStatusStream,
515}
516
517impl TransactionProgressError {
518 fn backend_error(&self) -> Option<&BackendError> {
519 match self {
520 TransactionProgressError::CannotGetNextProgressUpdate(e) => Some(e),
521 TransactionProgressError::TransactionStatusError(_) => None,
522 TransactionProgressError::UnexpectedEndOfTransactionStatusStream => None,
523 }
524 }
525}
526
527#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
529#[non_exhaustive]
530#[allow(missing_docs)]
531pub enum TransactionStatusError {
532 #[error("Error handling transaction: {0}")]
534 Error(String),
535 #[error("The transaction is not valid: {0}")]
537 Invalid(String),
538 #[error("The transaction was dropped: {0}")]
540 Dropped(String),
541}
542
543#[derive(Debug, thiserror::Error)]
545#[non_exhaustive]
546#[allow(missing_docs)]
547pub enum TransactionEventsError {
548 #[error(
549 "The block containing the submitted transaction ({block_hash}) could not be downloaded: {error}"
550 )]
551 CannotFetchBlockBody { block_hash: Hex, error: BackendError },
552 #[error(
553 "Cannot find the the submitted transaction (hash: {transaction_hash}) in the block (hash: {block_hash}) it is supposed to be in."
554 )]
555 CannotFindTransactionInBlock { block_hash: Hex, transaction_hash: Hex },
556 #[error("The block containing the submitted transaction ({block_hash}) could not be found")]
557 BlockNotFound { block_hash: Hex },
558 #[error(
559 "Could not decode event at index {event_index} for the submitted transaction at block {block_hash}: {error}"
560 )]
561 CannotDecodeEventInBlock { event_index: usize, block_hash: Hex, error: EventsError },
562 #[error("Could not fetch events for the submitted transaction: {error}")]
563 CannotFetchEventsForTransaction { block_hash: Hex, transaction_hash: Hex, error: EventsError },
564 #[error("The transaction led to a DispatchError, but we failed to decode it: {error}")]
565 CannotDecodeDispatchError { error: DispatchErrorDecodeError, bytes: Vec<u8> },
566 #[error("The transaction failed with the following dispatch error: {0}")]
567 ExtrinsicFailed(#[from] DispatchError),
568}
569
570impl TransactionEventsError {
571 fn backend_error(&self) -> Option<&BackendError> {
572 match self {
573 TransactionEventsError::CannotFetchBlockBody { error, .. } => Some(error),
574 TransactionEventsError::CannotDecodeEventInBlock { error, .. }
575 | TransactionEventsError::CannotFetchEventsForTransaction { error, .. } => error.backend_error(),
576 _ => None,
577 }
578 }
579}
580
581#[derive(Debug, thiserror::Error)]
583#[non_exhaustive]
584#[allow(missing_docs, clippy::large_enum_variant)]
585pub enum TransactionFinalizedSuccessError {
586 #[error("Could not finalize the transaction: {0}")]
587 FinalizationError(#[from] TransactionProgressError),
588 #[error("The transaction did not succeed: {0}")]
589 SuccessError(#[from] TransactionEventsError),
590}
591
592impl TransactionFinalizedSuccessError {
593 fn backend_error(&self) -> Option<&BackendError> {
594 match self {
595 TransactionFinalizedSuccessError::FinalizationError(e) => e.backend_error(),
596 TransactionFinalizedSuccessError::SuccessError(e) => e.backend_error(),
597 }
598 }
599}
600
601#[derive(Debug, thiserror::Error)]
603#[non_exhaustive]
604#[allow(missing_docs)]
605pub enum ModuleErrorDetailsError {
606 #[error(
607 "Could not get details for the DispatchError: could not find pallet index {pallet_index}"
608 )]
609 PalletNotFound { pallet_index: u8 },
610 #[error(
611 "Could not get details for the DispatchError: could not find error index {error_index} in pallet {pallet_name}"
612 )]
613 ErrorVariantNotFound { pallet_name: String, error_index: u8 },
614}
615
616#[derive(Debug, thiserror::Error)]
618#[non_exhaustive]
619#[allow(missing_docs)]
620#[error("Could not decode the DispatchError::Module payload into the given type: {0}")]
621pub struct ModuleErrorDecodeError(scale_decode::Error);
622
623#[derive(Debug, thiserror::Error)]
625#[non_exhaustive]
626#[allow(missing_docs)]
627pub enum DispatchErrorDecodeError {
628 #[error(
629 "Could not decode the DispatchError: could not find the corresponding type ID in the metadata"
630 )]
631 DispatchErrorTypeIdNotFound,
632 #[error("Could not decode the DispatchError: {0}")]
633 CouldNotDecodeDispatchError(scale_decode::Error),
634 #[error("Could not decode the DispatchError::Module variant")]
635 CouldNotDecodeModuleError {
636 bytes: Vec<u8>,
638 },
639}
640
641#[derive(Debug, thiserror::Error)]
643#[non_exhaustive]
644#[allow(missing_docs)]
645pub enum StorageError {
646 #[error("{0}")]
647 Offline(#[from] CoreStorageError),
648 #[error("Cannot access storage at latest block: Cannot fetch latest finalized block: {0}")]
649 CannotGetLatestFinalizedBlock(BackendError),
650 #[error(
651 "No storage value found at the given address, and no default value to fall back to using."
652 )]
653 NoValueFound,
654 #[error("Cannot fetch the storage value: {0}")]
655 CannotFetchValue(BackendError),
656 #[error("Cannot iterate storage values: {0}")]
657 CannotIterateValues(BackendError),
658 #[error("Encountered an error iterating over storage values: {0}")]
659 StreamFailure(BackendError),
660 #[error("Cannot decode the storage version for a given entry: {0}")]
661 CannotDecodeStorageVersion(codec::Error),
662}
663
664impl StorageError {
665 fn backend_error(&self) -> Option<&BackendError> {
666 match self {
667 StorageError::CannotGetLatestFinalizedBlock(e)
668 | StorageError::CannotFetchValue(e)
669 | StorageError::CannotIterateValues(e)
670 | StorageError::StreamFailure(e) => Some(e),
671 _ => None,
672 }
673 }
674}