1use std::{mem::discriminant, sync::Arc};
2
3use alloy::transports::{RpcError, TransportErrorKind};
4use thiserror::Error;
5
6use crate::types::ScannerResult;
7
8use robust_provider::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(err),
68 RobustProviderError::BlockNotFound => ScannerError::BlockNotFound,
69 }
70 }
71}
72
73impl From<RpcError<TransportErrorKind>> for ScannerError {
74 fn from(error: RpcError<TransportErrorKind>) -> Self {
75 ScannerError::RpcError(Arc::new(error))
76 }
77}
78
79impl<T: Clone> PartialEq<ScannerError> for ScannerResult<T> {
80 fn eq(&self, other: &ScannerError) -> bool {
81 match self {
82 Ok(_) => false,
83 Err(err) => discriminant(err) == discriminant(other),
84 }
85 }
86}