1use std::{mem::discriminant, sync::Arc};
2
3use alloy::{
4 eips::BlockId,
5 transports::{RpcError, TransportErrorKind},
6};
7use thiserror::Error;
8
9use crate::{robust_provider::provider::Error as RobustProviderError, types::ScannerResult};
10
11#[derive(Error, Debug, Clone)]
12pub enum ScannerError {
13 #[error("RPC error: {0}")]
14 RpcError(Arc<RpcError<TransportErrorKind>>),
15
16 #[error("Service is shutting down")]
17 ServiceShutdown,
18
19 #[error("Block not found, Block Id: {0}")]
20 BlockNotFound(BlockId),
21
22 #[error("Operation timed out")]
23 Timeout,
24
25 #[error("{0} {1} exceeds the latest block {2}")]
26 BlockExceedsLatest(&'static str, u64, u64),
27
28 #[error("Event count must be greater than 0")]
29 InvalidEventCount,
30
31 #[error("Max block range must be greater than 0")]
32 InvalidMaxBlockRange,
33
34 #[error("Subscription closed")]
35 SubscriptionClosed,
36}
37
38impl From<RobustProviderError> for ScannerError {
39 fn from(error: RobustProviderError) -> ScannerError {
40 match error {
41 RobustProviderError::Timeout => ScannerError::Timeout,
42 RobustProviderError::RpcError(err) => ScannerError::RpcError(err),
43 RobustProviderError::BlockNotFound(block) => ScannerError::BlockNotFound(block),
44 }
45 }
46}
47
48impl From<RpcError<TransportErrorKind>> for ScannerError {
49 fn from(error: RpcError<TransportErrorKind>) -> Self {
50 ScannerError::RpcError(Arc::new(error))
51 }
52}
53
54impl<T: Clone> PartialEq<ScannerError> for ScannerResult<T> {
55 fn eq(&self, other: &ScannerError) -> bool {
56 match self {
57 Ok(_) => false,
58 Err(err) => discriminant(err) == discriminant(other),
59 }
60 }
61}