/Users/andrewlamb/Software/arrow-rs/arrow-schema/src/error.rs
Line | Count | Source |
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. |
17 | | |
18 | | //! Defines `ArrowError` for representing failures in various Arrow operations. |
19 | | use std::fmt::{Debug, Display, Formatter}; |
20 | | use std::io::Write; |
21 | | |
22 | | use std::error::Error; |
23 | | |
24 | | /// Many different operations in the `arrow` crate return this error type. |
25 | | #[derive(Debug)] |
26 | | pub enum ArrowError { |
27 | | /// Returned when functionality is not yet available. |
28 | | NotYetImplemented(String), |
29 | | /// Wraps an external error. |
30 | | ExternalError(Box<dyn Error + Send + Sync>), |
31 | | /// Error during casting from one type to another. |
32 | | CastError(String), |
33 | | /// Memory or buffer error. |
34 | | MemoryError(String), |
35 | | /// Error during parsing from a string. |
36 | | ParseError(String), |
37 | | /// Error during schema-related operations. |
38 | | SchemaError(String), |
39 | | /// Error during computation. |
40 | | ComputeError(String), |
41 | | /// Error during division by zero. |
42 | | DivideByZero, |
43 | | /// Error when an arithmetic operation overflows. |
44 | | ArithmeticOverflow(String), |
45 | | /// Error during CSV-related operations. |
46 | | CsvError(String), |
47 | | /// Error during JSON-related operations. |
48 | | JsonError(String), |
49 | | /// Error during IO operations. |
50 | | IoError(String, std::io::Error), |
51 | | /// Error during IPC operations in `arrow-ipc` or `arrow-flight`. |
52 | | IpcError(String), |
53 | | /// Error indicating that an unexpected or bad argument was passed to a function. |
54 | | InvalidArgumentError(String), |
55 | | /// Error during Parquet operations. |
56 | | ParquetError(String), |
57 | | /// Error during import or export to/from the C Data Interface |
58 | | CDataInterface(String), |
59 | | /// Error when a dictionary key is bigger than the key type |
60 | | DictionaryKeyOverflowError, |
61 | | /// Error when the run end index in a REE array is bigger than the array length |
62 | | RunEndIndexOverflowError, |
63 | | /// Error when the offset overflows. |
64 | | OffsetOverflowError(usize), |
65 | | } |
66 | | |
67 | | impl ArrowError { |
68 | | /// Wraps an external error in an `ArrowError`. |
69 | 0 | pub fn from_external_error(error: Box<dyn Error + Send + Sync>) -> Self { |
70 | 0 | Self::ExternalError(error) |
71 | 0 | } |
72 | | } |
73 | | |
74 | | impl From<std::io::Error> for ArrowError { |
75 | 0 | fn from(error: std::io::Error) -> Self { |
76 | 0 | ArrowError::IoError(error.to_string(), error) |
77 | 0 | } |
78 | | } |
79 | | |
80 | | impl From<std::str::Utf8Error> for ArrowError { |
81 | 0 | fn from(error: std::str::Utf8Error) -> Self { |
82 | 0 | ArrowError::ParseError(error.to_string()) |
83 | 0 | } |
84 | | } |
85 | | |
86 | | impl From<std::string::FromUtf8Error> for ArrowError { |
87 | 0 | fn from(error: std::string::FromUtf8Error) -> Self { |
88 | 0 | ArrowError::ParseError(error.to_string()) |
89 | 0 | } |
90 | | } |
91 | | |
92 | | impl<W: Write> From<std::io::IntoInnerError<W>> for ArrowError { |
93 | 0 | fn from(error: std::io::IntoInnerError<W>) -> Self { |
94 | 0 | ArrowError::IoError(error.to_string(), error.into()) |
95 | 0 | } |
96 | | } |
97 | | |
98 | | impl Display for ArrowError { |
99 | 8 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
100 | 8 | match self { |
101 | 1 | ArrowError::NotYetImplemented(source) => { |
102 | 1 | write!(f, "Not yet implemented: {}", &source) |
103 | | } |
104 | 0 | ArrowError::ExternalError(source) => write!(f, "External error: {}", &source), |
105 | 0 | ArrowError::CastError(desc) => write!(f, "Cast error: {desc}"), |
106 | 0 | ArrowError::MemoryError(desc) => write!(f, "Memory error: {desc}"), |
107 | 5 | ArrowError::ParseError(desc) => write!(f, "Parser error: {desc}"), |
108 | 2 | ArrowError::SchemaError(desc) => write!(f, "Schema error: {desc}"), |
109 | 0 | ArrowError::ComputeError(desc) => write!(f, "Compute error: {desc}"), |
110 | 0 | ArrowError::ArithmeticOverflow(desc) => write!(f, "Arithmetic overflow: {desc}"), |
111 | 0 | ArrowError::DivideByZero => write!(f, "Divide by zero error"), |
112 | 0 | ArrowError::CsvError(desc) => write!(f, "Csv error: {desc}"), |
113 | 0 | ArrowError::JsonError(desc) => write!(f, "Json error: {desc}"), |
114 | 0 | ArrowError::IoError(desc, _) => write!(f, "Io error: {desc}"), |
115 | 0 | ArrowError::IpcError(desc) => write!(f, "Ipc error: {desc}"), |
116 | 0 | ArrowError::InvalidArgumentError(desc) => { |
117 | 0 | write!(f, "Invalid argument error: {desc}") |
118 | | } |
119 | 0 | ArrowError::ParquetError(desc) => { |
120 | 0 | write!(f, "Parquet argument error: {desc}") |
121 | | } |
122 | 0 | ArrowError::CDataInterface(desc) => { |
123 | 0 | write!(f, "C Data interface error: {desc}") |
124 | | } |
125 | | ArrowError::DictionaryKeyOverflowError => { |
126 | 0 | write!(f, "Dictionary key bigger than the key type") |
127 | | } |
128 | | ArrowError::RunEndIndexOverflowError => { |
129 | 0 | write!(f, "Run end encoded array index overflow error") |
130 | | } |
131 | 0 | ArrowError::OffsetOverflowError(offset) => { |
132 | 0 | write!(f, "Offset overflow error: {offset}") |
133 | | } |
134 | | } |
135 | 8 | } |
136 | | } |
137 | | |
138 | | impl Error for ArrowError { |
139 | 0 | fn source(&self) -> Option<&(dyn Error + 'static)> { |
140 | 0 | match self { |
141 | 0 | ArrowError::ExternalError(source) => Some(source.as_ref()), |
142 | 0 | ArrowError::IoError(_, source) => Some(source), |
143 | 0 | _ => None, |
144 | | } |
145 | 0 | } |
146 | | } |
147 | | |
148 | | #[cfg(test)] |
149 | | mod test { |
150 | | use super::*; |
151 | | |
152 | | #[test] |
153 | | fn error_source() { |
154 | | let e1 = ArrowError::DivideByZero; |
155 | | assert!(e1.source().is_none()); |
156 | | |
157 | | // one level of wrapping |
158 | | let e2 = ArrowError::ExternalError(Box::new(e1)); |
159 | | let source = e2.source().unwrap().downcast_ref::<ArrowError>().unwrap(); |
160 | | assert!(matches!(source, ArrowError::DivideByZero)); |
161 | | |
162 | | // two levels of wrapping |
163 | | let e3 = ArrowError::ExternalError(Box::new(e2)); |
164 | | let source = e3 |
165 | | .source() |
166 | | .unwrap() |
167 | | .downcast_ref::<ArrowError>() |
168 | | .unwrap() |
169 | | .source() |
170 | | .unwrap() |
171 | | .downcast_ref::<ArrowError>() |
172 | | .unwrap(); |
173 | | |
174 | | assert!(matches!(source, ArrowError::DivideByZero)); |
175 | | } |
176 | | } |