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}