1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// SPDX-FileCopyrightText: 2025 Semiotic AI, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//! Error types for the semioscan library.
//!
//! This module provides strongly-typed errors for all public APIs in semioscan.
//! It follows a hybrid approach:
//!
//! - **Module-specific errors** for fine-grained error handling (`BlockWindowError`,
//! `GasCalculationError`, etc.)
//! - **Unified error type** (`SemioscanError`) for convenience when you don't need
//! to distinguish between error sources
//!
//! # Architecture
//!
//! Each major module has its own error type:
//! - [`BlockWindowError`] - Errors from block window calculations
//! - [`GasCalculationError`] - Errors from gas cost calculations
//! - [`PriceCalculationError`] - Errors from price calculations (wraps [`crate::price::PriceSourceError`])
//! - [`EventProcessingError`] - Errors from event scanning and processing
//! - [`RetrievalError`] - Errors from combined data retrieval operations
//!
//! Additionally, [`RpcError`] provides shared error variants for blockchain RPC operations.
//!
//! # Examples
//!
//! ## Fine-grained error handling
//!
//! ```rust,ignore
//! use semioscan::{BlockWindowCalculator, BlockWindowError};
//! use alloy_chains::NamedChain;
//! use chrono::NaiveDate;
//!
//! async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let calculator = BlockWindowCalculator::with_disk_cache(provider, "cache.json")?;
//! let date = NaiveDate::from_ymd_opt(2024, 1, 15).unwrap();
//!
//! match calculator.get_daily_window(NamedChain::Arbitrum, date).await {
//! Ok(window) => println!("Block window: {:?}", window),
//! Err(BlockWindowError::InvalidRange { reason }) => {
//! eprintln!("Invalid range: {}", reason);
//! }
//! Err(BlockWindowError::Rpc(rpc_err)) => {
//! eprintln!("RPC failure, retrying...: {}", rpc_err);
//! }
//! Err(e) => eprintln!("Other error: {}", e),
//! }
//! Ok(())
//! }
//! ```
//!
//! ## Using the unified error type
//!
//! ```rust,ignore
//! use semioscan::{SemioscanError, BlockWindowCalculator};
//! use alloy_chains::NamedChain;
//! use chrono::NaiveDate;
//!
//! async fn example() -> Result<(), SemioscanError> {
//! let calculator = BlockWindowCalculator::with_disk_cache(provider, "cache.json")?;
//! let date = NaiveDate::from_ymd_opt(2024, 1, 15).unwrap();
//! let window = calculator.get_daily_window(NamedChain::Arbitrum, date).await?;
//! // Errors automatically convert to SemioscanError via From implementations
//! Ok(())
//! }
//! ```
pub use BlockWindowError;
pub use EventProcessingError;
pub use GasCalculationError;
pub use PriceCalculationError;
pub use RetrievalError;
pub use RpcError;
/// Unified error type for all semioscan operations.
///
/// This enum wraps all module-specific error types, providing a convenient way to
/// handle errors when you don't need to distinguish between different error sources.
///
/// All module-specific error types automatically convert to `SemioscanError` via
/// `From` implementations, so you can use `?` to propagate errors naturally.
///
/// # Examples
///
/// ```rust,ignore
/// use semioscan::{SemioscanError, BlockWindowCalculator, GasCostCalculator};
/// use alloy_chains::NamedChain;
/// use chrono::NaiveDate;
///
/// async fn process_data() -> Result<(), SemioscanError> {
/// let block_calc = BlockWindowCalculator::with_disk_cache(provider, "cache.json")?;
/// let gas_calc = GasCostCalculator::new(provider);
///
/// // Both error types automatically convert to SemioscanError
/// let date = NaiveDate::from_ymd_opt(2024, 1, 15).unwrap();
/// let window = block_calc.get_daily_window(NamedChain::Arbitrum, date).await?;
/// let gas_cost = gas_calc.calculate_gas_cost_for_transfers_between_blocks(
/// NamedChain::Arbitrum, from_address, to_address, token_address, start_block, end_block
/// ).await?;
///
/// Ok(())
/// }
/// ```