1use std::{mem::discriminant, sync::Arc};
2
3use alloy::transports::{RpcError, TransportErrorKind};
4use thiserror::Error;
5
6use crate::types::ScannerResult;
7
8use robust_provider::Error as RobustProviderError;
9
10#[derive(Error, Debug, Clone)]
17pub enum ScannerError {
18 #[error("RPC error: {0}")]
20 RpcError(Arc<RpcError<TransportErrorKind>>),
21
22 #[error("Block not found")]
24 BlockNotFound,
25
26 #[error("Operation timed out")]
28 Timeout,
29
30 #[error("{0} {1} exceeds the latest block {2}")]
32 BlockExceedsLatest(&'static str, u64, u64),
33
34 #[error("Event count must be greater than 0")]
36 InvalidEventCount,
37
38 #[error("Max block range must be greater than 0")]
40 InvalidMaxBlockRange,
41
42 #[error("Stream buffer capacity must be greater than 0")]
44 InvalidBufferCapacity,
45
46 #[error("Max concurrent fetches must be greater than 0")]
49 InvalidMaxConcurrentFetches,
50
51 #[error("Subscription closed")]
53 SubscriptionClosed,
54
55 #[error("Subscription lagged")]
60 Lagged(u64),
61}
62
63impl From<RobustProviderError> for ScannerError {
64 fn from(error: RobustProviderError) -> ScannerError {
65 match error {
66 RobustProviderError::Timeout => ScannerError::Timeout,
67 RobustProviderError::RpcError(err) => ScannerError::RpcError(Arc::new(err)),
68 RobustProviderError::BlockNotFound => ScannerError::BlockNotFound,
69 RobustProviderError::Lagged(blocks) => ScannerError::Lagged(blocks),
70 RobustProviderError::Closed => ScannerError::SubscriptionClosed,
71 }
72 }
73}
74
75impl From<RpcError<TransportErrorKind>> for ScannerError {
76 fn from(error: RpcError<TransportErrorKind>) -> Self {
77 ScannerError::RpcError(Arc::new(error))
78 }
79}
80
81impl<T: Clone> PartialEq<ScannerError> for ScannerResult<T> {
82 fn eq(&self, other: &ScannerError) -> bool {
83 match self {
84 Ok(_) => false,
85 Err(err) => discriminant(err) == discriminant(other),
86 }
87 }
88}