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}