typed_arrow_dyn/
error.rs

1//! Error types for dynamic builders and rows.
2
3use arrow_schema::DataType;
4use thiserror::Error;
5
6/// Errors that can occur when appending dynamic rows/cells.
7#[derive(Debug, Error)]
8pub enum DynError {
9    /// The number of cells in a row did not match the schema width.
10    #[error("row length {got} does not match schema width {expected}")]
11    ArityMismatch {
12        /// Expected number of columns (schema width).
13        expected: usize,
14        /// Actual number of cells present in the provided row.
15        got: usize,
16    },
17
18    /// Post-build nullability violation detected by the validator.
19    #[error("nullability violation at column {col} ({path}) index {index}: {message}")]
20    Nullability {
21        /// Top-level column index where the violation occurred.
22        col: usize,
23        /// Dot-annotated path to the offending field (e.g., "`struct_field.child`[]").
24        path: String,
25        /// Row or value index where the violation was found.
26        index: usize,
27        /// Message describing the violation.
28        message: String,
29    },
30
31    /// A cell's Rust value did not match the target Arrow `DataType` for a column.
32    #[error("type mismatch at column {col}: expected {expected:?}")]
33    TypeMismatch {
34        /// The zero-based column index where the mismatch occurred.
35        col: usize,
36        /// The Arrow logical type expected for that column.
37        expected: DataType,
38    },
39
40    /// The underlying Arrow builder reported an error while appending a value.
41    #[error("builder error: {message}")]
42    Builder {
43        /// Human-readable error from the underlying Arrow builder.
44        message: String,
45    },
46
47    /// Append failed at a specific column with a message.
48    #[error("append error at column {col}: {message}")]
49    Append {
50        /// The zero-based column index where the builder failed.
51        col: usize,
52        /// Human-readable error message from the builder.
53        message: String,
54    },
55}
56
57impl DynError {
58    /// Add column context to a builder error.
59    #[must_use]
60    pub fn at_col(self, col: usize) -> DynError {
61        match self {
62            DynError::Builder { message } => DynError::Append { col, message },
63            other => other,
64        }
65    }
66}
67
68/// Errors that can occur when constructing dynamic views over Arrow data.
69#[derive(Debug, Error)]
70pub enum DynViewError {
71    /// Requested row index exceeded the batch length.
72    #[error("row index {row} out of bounds for batch length {len}")]
73    RowOutOfBounds {
74        /// Provided row index.
75        row: usize,
76        /// Total number of rows in the batch.
77        len: usize,
78    },
79
80    /// Requested column index exceeded the schema width.
81    #[error("column index {column} out of bounds for schema width {width}")]
82    ColumnOutOfBounds {
83        /// Provided column index.
84        column: usize,
85        /// Number of columns in the schema.
86        width: usize,
87    },
88
89    /// Column schema did not match the array data type present in the `RecordBatch`.
90    #[error(
91        "schema mismatch at column {column} ('{field}'): expected {expected:?}, got {actual:?}"
92    )]
93    SchemaMismatch {
94        /// Column index.
95        column: usize,
96        /// Column field name.
97        field: String,
98        /// Expected Arrow data type.
99        expected: DataType,
100        /// Actual Arrow data type encountered.
101        actual: DataType,
102    },
103
104    /// Array downcast failed due to an unexpected runtime type.
105    #[error("type mismatch at {path}: expected {expected:?}, got {actual:?}")]
106    TypeMismatch {
107        /// Column index.
108        column: usize,
109        /// Dot/segment annotated path within the column.
110        path: String,
111        /// Expected Arrow data type.
112        expected: DataType,
113        /// Actual Arrow data type encountered.
114        actual: DataType,
115    },
116
117    /// Encountered a null value where a non-null was required.
118    #[error("unexpected null at {path}")]
119    UnexpectedNull {
120        /// Column index.
121        column: usize,
122        /// Dot/segment annotated path within the column.
123        path: String,
124    },
125
126    /// Invalid data encountered while materializing a view.
127    #[error("invalid data at {path}: {message}")]
128    Invalid {
129        /// Column index.
130        column: usize,
131        /// Dot/segment annotated path within the column.
132        path: String,
133        /// Explanation of the invalid condition.
134        message: String,
135    },
136}