Skip to main content

scirs2_core/arrow_compat/
error.rs

1//! Error types for Arrow interoperability
2//!
3//! Provides specialized error types for Arrow ↔ ndarray conversions,
4//! IPC serialization, and schema operations.
5
6use crate::error::{CoreError, ErrorContext};
7use std::fmt;
8
9/// Errors that can occur during Arrow interoperability operations
10#[derive(Debug)]
11pub enum ArrowCompatError {
12    /// Type mismatch between expected and actual Arrow data types
13    TypeMismatch { expected: String, actual: String },
14    /// Shape mismatch when converting between Arrow and ndarray
15    ShapeMismatch {
16        expected: Vec<usize>,
17        actual: Vec<usize>,
18    },
19    /// Column index out of bounds in a RecordBatch
20    ColumnOutOfBounds { index: usize, num_columns: usize },
21    /// Column name not found in a RecordBatch
22    ColumnNotFound { name: String },
23    /// Null values encountered where not expected
24    NullValuesPresent {
25        null_count: usize,
26        total_count: usize,
27    },
28    /// Error from the underlying Arrow library
29    ArrowError(arrow::error::ArrowError),
30    /// I/O error during IPC operations
31    IoError(std::io::Error),
32    /// Schema validation error
33    SchemaError(String),
34    /// Zero-copy operation not possible
35    ZeroCopyNotPossible(String),
36    /// Inconsistent column lengths in a RecordBatch
37    InconsistentColumnLengths {
38        expected_len: usize,
39        column_index: usize,
40        column_len: usize,
41    },
42}
43
44impl fmt::Display for ArrowCompatError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            Self::TypeMismatch { expected, actual } => {
48                write!(
49                    f,
50                    "Arrow type mismatch: expected {}, got {}",
51                    expected, actual
52                )
53            }
54            Self::ShapeMismatch { expected, actual } => {
55                write!(
56                    f,
57                    "Shape mismatch: expected {:?}, got {:?}",
58                    expected, actual
59                )
60            }
61            Self::ColumnOutOfBounds { index, num_columns } => {
62                write!(
63                    f,
64                    "Column index {} out of bounds (num_columns={})",
65                    index, num_columns
66                )
67            }
68            Self::ColumnNotFound { name } => {
69                write!(f, "Column '{}' not found in RecordBatch", name)
70            }
71            Self::NullValuesPresent {
72                null_count,
73                total_count,
74            } => {
75                write!(
76                    f,
77                    "Found {} null values out of {} total (use nullable conversion instead)",
78                    null_count, total_count
79                )
80            }
81            Self::ArrowError(e) => write!(f, "Arrow error: {}", e),
82            Self::IoError(e) => write!(f, "I/O error: {}", e),
83            Self::SchemaError(msg) => write!(f, "Schema error: {}", msg),
84            Self::ZeroCopyNotPossible(reason) => {
85                write!(f, "Zero-copy not possible: {}", reason)
86            }
87            Self::InconsistentColumnLengths {
88                expected_len,
89                column_index,
90                column_len,
91            } => {
92                write!(
93                    f,
94                    "Inconsistent column lengths: expected {} rows, column {} has {} rows",
95                    expected_len, column_index, column_len
96                )
97            }
98        }
99    }
100}
101
102impl std::error::Error for ArrowCompatError {
103    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
104        match self {
105            Self::ArrowError(e) => Some(e),
106            Self::IoError(e) => Some(e),
107            _ => None,
108        }
109    }
110}
111
112impl From<arrow::error::ArrowError> for ArrowCompatError {
113    fn from(e: arrow::error::ArrowError) -> Self {
114        Self::ArrowError(e)
115    }
116}
117
118impl From<std::io::Error> for ArrowCompatError {
119    fn from(e: std::io::Error) -> Self {
120        Self::IoError(e)
121    }
122}
123
124impl From<ArrowCompatError> for CoreError {
125    fn from(e: ArrowCompatError) -> Self {
126        CoreError::ComputationError(ErrorContext::new(format!("Arrow interop: {}", e)))
127    }
128}
129
130/// Result type for Arrow interoperability operations
131pub type ArrowResult<T> = Result<T, ArrowCompatError>;