1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
1718//! Defines `ArrowError` for representing failures in various Arrow operations.
19use std::fmt::{Debug, Display, Formatter};
20use std::io::Write;
2122use std::error::Error;
2324/// Many different operations in the `arrow` crate return this error type.
25#[derive(Debug)]
26pub enum ArrowError {
27/// Returned when functionality is not yet available.
28NotYetImplemented(String),
29/// Wraps an external error.
30ExternalError(Box<dyn Error + Send + Sync>),
31/// Error during casting from one type to another.
32CastError(String),
33/// Memory or buffer error.
34MemoryError(String),
35/// Error during parsing from a string.
36ParseError(String),
37/// Error during schema-related operations.
38SchemaError(String),
39/// Error during computation.
40ComputeError(String),
41/// Error during division by zero.
42DivideByZero,
43/// Error when an arithmetic operation overflows.
44ArithmeticOverflow(String),
45/// Error during CSV-related operations.
46CsvError(String),
47/// Error during JSON-related operations.
48JsonError(String),
49/// Error during IO operations.
50IoError(String, std::io::Error),
51/// Error during IPC operations in `arrow-ipc` or `arrow-flight`.
52IpcError(String),
53/// Error indicating that an unexpected or bad argument was passed to a function.
54InvalidArgumentError(String),
55/// Error during Parquet operations.
56ParquetError(String),
57/// Error during import or export to/from the C Data Interface
58CDataInterface(String),
59/// Error when a dictionary key is bigger than the key type
60DictionaryKeyOverflowError,
61/// Error when the run end index in a REE array is bigger than the array length
62RunEndIndexOverflowError,
63}
6465impl ArrowError {
66/// Wraps an external error in an `ArrowError`.
67pub fn from_external_error(error: Box<dyn Error + Send + Sync>) -> Self {
68Self::ExternalError(error)
69 }
70}
7172impl From<std::io::Error> for ArrowError {
73fn from(error: std::io::Error) -> Self {
74 ArrowError::IoError(error.to_string(), error)
75 }
76}
7778impl From<std::str::Utf8Error> for ArrowError {
79fn from(error: std::str::Utf8Error) -> Self {
80 ArrowError::ParseError(error.to_string())
81 }
82}
8384impl From<std::string::FromUtf8Error> for ArrowError {
85fn from(error: std::string::FromUtf8Error) -> Self {
86 ArrowError::ParseError(error.to_string())
87 }
88}
8990impl<W: Write> From<std::io::IntoInnerError<W>> for ArrowError {
91fn from(error: std::io::IntoInnerError<W>) -> Self {
92 ArrowError::IoError(error.to_string(), error.into())
93 }
94}
9596impl Display for ArrowError {
97fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
98match self {
99 ArrowError::NotYetImplemented(source) => {
100write!(f, "Not yet implemented: {}", &source)
101 }
102 ArrowError::ExternalError(source) => write!(f, "External error: {}", &source),
103 ArrowError::CastError(desc) => write!(f, "Cast error: {desc}"),
104 ArrowError::MemoryError(desc) => write!(f, "Memory error: {desc}"),
105 ArrowError::ParseError(desc) => write!(f, "Parser error: {desc}"),
106 ArrowError::SchemaError(desc) => write!(f, "Schema error: {desc}"),
107 ArrowError::ComputeError(desc) => write!(f, "Compute error: {desc}"),
108 ArrowError::ArithmeticOverflow(desc) => write!(f, "Arithmetic overflow: {desc}"),
109 ArrowError::DivideByZero => write!(f, "Divide by zero error"),
110 ArrowError::CsvError(desc) => write!(f, "Csv error: {desc}"),
111 ArrowError::JsonError(desc) => write!(f, "Json error: {desc}"),
112 ArrowError::IoError(desc, _) => write!(f, "Io error: {desc}"),
113 ArrowError::IpcError(desc) => write!(f, "Ipc error: {desc}"),
114 ArrowError::InvalidArgumentError(desc) => {
115write!(f, "Invalid argument error: {desc}")
116 }
117 ArrowError::ParquetError(desc) => {
118write!(f, "Parquet argument error: {desc}")
119 }
120 ArrowError::CDataInterface(desc) => {
121write!(f, "C Data interface error: {desc}")
122 }
123 ArrowError::DictionaryKeyOverflowError => {
124write!(f, "Dictionary key bigger than the key type")
125 }
126 ArrowError::RunEndIndexOverflowError => {
127write!(f, "Run end encoded array index overflow error")
128 }
129 }
130 }
131}
132133impl Error for ArrowError {
134fn source(&self) -> Option<&(dyn Error + 'static)> {
135match self {
136 ArrowError::ExternalError(source) => Some(source.as_ref()),
137 ArrowError::IoError(_, source) => Some(source),
138_ => None,
139 }
140 }
141}
142143#[cfg(test)]
144mod test {
145use super::*;
146147#[test]
148fn error_source() {
149let e1 = ArrowError::DivideByZero;
150assert!(e1.source().is_none());
151152// one level of wrapping
153let e2 = ArrowError::ExternalError(Box::new(e1));
154let source = e2.source().unwrap().downcast_ref::<ArrowError>().unwrap();
155assert!(matches!(source, ArrowError::DivideByZero));
156157// two levels of wrapping
158let e3 = ArrowError::ExternalError(Box::new(e2));
159let source = e3
160 .source()
161 .unwrap()
162 .downcast_ref::<ArrowError>()
163 .unwrap()
164 .source()
165 .unwrap()
166 .downcast_ref::<ArrowError>()
167 .unwrap();
168169assert!(matches!(source, ArrowError::DivideByZero));
170 }
171}