rust_data_processing/
error.rs

1use std::error::Error as StdError;
2
3use thiserror::Error;
4
5/// Convenience result type for ingestion operations.
6pub type IngestionResult<T> = Result<T, IngestionError>;
7
8/// Error type returned by ingestion functions.
9///
10/// This is a single error enum shared across CSV/JSON/Parquet/Excel ingestion.
11#[derive(Debug, Error)]
12pub enum IngestionError {
13    /// Underlying I/O error (e.g. file not found, permission denied).
14    #[error("io error: {0}")]
15    Io(#[from] std::io::Error),
16
17    /// Excel ingestion error.
18    #[cfg(feature = "excel")]
19    #[error("excel error: {0}")]
20    Excel(#[from] calamine::Error),
21
22    /// CSV ingestion error.
23    #[error("csv error: {0}")]
24    Csv(#[from] csv::Error),
25
26    /// Parquet ingestion error.
27    #[error("parquet error: {0}")]
28    Parquet(#[from] parquet::errors::ParquetError),
29
30    /// Underlying engine error (e.g. Polars, optional SQL engine), preserved with a source chain.
31    ///
32    /// This is used when the engine produces a structured error that callers may want to inspect
33    /// or log in detail. The top-level message is a stable, human-readable summary, while the
34    /// original engine error is preserved via [`std::error::Error::source`].
35    #[error("{message}: {source}")]
36    Engine {
37        message: String,
38        #[source]
39        source: Box<dyn StdError + Send + Sync + 'static>,
40    },
41
42    /// The input does not conform to the provided schema (missing required fields/columns, etc.).
43    #[error("schema mismatch: {message}")]
44    SchemaMismatch { message: String },
45
46    /// A value could not be parsed into the required [`crate::types::DataType`].
47    #[error("failed to parse value at row {row} column '{column}': {message} (raw='{raw}')")]
48    ParseError {
49        row: usize,
50        column: String,
51        raw: String,
52        message: String,
53    },
54}