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("Max concurrent fetches must be greater than 0")]
35 InvalidMaxConcurrentFetches,
36
37 #[error("Subscription closed")]
38 SubscriptionClosed,
39}
40
41impl From<RobustProviderError> for ScannerError {
42 fn from(error: RobustProviderError) -> ScannerError {
43 match error {
44 RobustProviderError::Timeout => ScannerError::Timeout,
45 RobustProviderError::RpcError(err) => ScannerError::RpcError(err),
46 RobustProviderError::BlockNotFound(block) => ScannerError::BlockNotFound(block),
47 }
48 }
49}
50
51impl From<RpcError<TransportErrorKind>> for ScannerError {
52 fn from(error: RpcError<TransportErrorKind>) -> Self {
53 ScannerError::RpcError(Arc::new(error))
54 }
55}
56
57impl<T: Clone> PartialEq<ScannerError> for ScannerResult<T> {
58 fn eq(&self, other: &ScannerError) -> bool {
59 match self {
60 Ok(_) => false,
61 Err(err) => discriminant(err) == discriminant(other),
62 }
63 }
64}