Skip to main content

arrow_avro/
errors.rs

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//! Common Avro errors and macros.
19
20use arrow_schema::ArrowError;
21use core::num::TryFromIntError;
22use std::error::Error;
23use std::string::FromUtf8Error;
24use std::{io, str};
25
26/// Avro error enumeration
27
28#[derive(Debug)]
29#[non_exhaustive]
30pub enum AvroError {
31    /// General Avro error.
32    /// Returned when code violates normal workflow of working with Avro data.
33    General(String),
34    /// "Not yet implemented" Avro error.
35    /// Returned when functionality is not yet available.
36    NYI(String),
37    /// "End of file" Avro error.
38    /// Returned when IO related failures occur, e.g. when there are not enough bytes to
39    /// decode.
40    EOF(String),
41    /// Arrow error.
42    /// Returned when reading into arrow or writing from arrow.
43    ArrowError(Box<ArrowError>),
44    /// Error when the requested index is more than the
45    /// number of items expected
46    IndexOutOfBound(usize, usize),
47    /// Error indicating that an unexpected or bad argument was passed to a function.
48    InvalidArgument(String),
49    /// Error indicating that a value could not be parsed.
50    ParseError(String),
51    /// Error indicating that a schema is invalid.
52    SchemaError(String),
53    /// An external error variant
54    External(Box<dyn Error + Send + Sync>),
55    /// Error during IO operations
56    IoError(String, io::Error),
57    /// Returned when a function needs more data to complete properly. The `usize` field indicates
58    /// the total number of bytes required, not the number of additional bytes.
59    NeedMoreData(usize),
60    /// Returned when a function needs more data to complete properly.
61    /// The `Range<u64>` indicates the range of bytes that are needed.
62    NeedMoreDataRange(std::ops::Range<u64>),
63    /// Returned when an unframed datum cannot be decoded until the current batch is flushed.
64    BatchFull,
65}
66
67impl std::fmt::Display for AvroError {
68    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
69        match &self {
70            AvroError::General(message) => {
71                write!(fmt, "Avro error: {message}")
72            }
73            AvroError::NYI(message) => write!(fmt, "NYI: {message}"),
74            AvroError::EOF(message) => write!(fmt, "EOF: {message}"),
75            AvroError::ArrowError(message) => write!(fmt, "Arrow: {message}"),
76            AvroError::IndexOutOfBound(index, bound) => {
77                write!(fmt, "Index {index} out of bound: {bound}")
78            }
79            AvroError::InvalidArgument(message) => {
80                write!(fmt, "Invalid argument: {message}")
81            }
82            AvroError::ParseError(message) => write!(fmt, "Parser error: {message}"),
83            AvroError::SchemaError(message) => write!(fmt, "Schema error: {message}"),
84            AvroError::External(e) => write!(fmt, "External: {e}"),
85            AvroError::IoError(message, e) => write!(fmt, "I/O Error: {message}: {e}"),
86            AvroError::NeedMoreData(needed) => write!(fmt, "NeedMoreData: {needed}"),
87            AvroError::NeedMoreDataRange(range) => {
88                write!(fmt, "NeedMoreDataRange: {}..{}", range.start, range.end)
89            }
90            AvroError::BatchFull => {
91                write!(fmt, "Batch is full; flush before decoding another datum")
92            }
93        }
94    }
95}
96
97impl Error for AvroError {
98    fn source(&self) -> Option<&(dyn Error + 'static)> {
99        match self {
100            AvroError::External(e) => Some(e.as_ref()),
101            AvroError::ArrowError(e) => Some(e.as_ref()),
102            AvroError::IoError(_, e) => Some(e),
103            _ => None,
104        }
105    }
106}
107
108impl From<TryFromIntError> for AvroError {
109    fn from(e: TryFromIntError) -> AvroError {
110        AvroError::General(format!("Integer overflow: {e}"))
111    }
112}
113
114impl From<io::Error> for AvroError {
115    fn from(e: io::Error) -> AvroError {
116        AvroError::External(Box::new(e))
117    }
118}
119
120impl From<str::Utf8Error> for AvroError {
121    fn from(e: str::Utf8Error) -> AvroError {
122        AvroError::External(Box::new(e))
123    }
124}
125
126impl From<FromUtf8Error> for AvroError {
127    fn from(e: FromUtf8Error) -> AvroError {
128        AvroError::External(Box::new(e))
129    }
130}
131
132impl From<ArrowError> for AvroError {
133    fn from(e: ArrowError) -> Self {
134        AvroError::ArrowError(Box::new(e))
135    }
136}
137
138#[cfg(feature = "object_store")]
139impl From<object_store::Error> for AvroError {
140    fn from(e: object_store::Error) -> AvroError {
141        AvroError::External(Box::new(e))
142    }
143}
144
145impl From<AvroError> for io::Error {
146    fn from(e: AvroError) -> Self {
147        io::Error::other(e)
148    }
149}
150
151impl From<AvroError> for ArrowError {
152    fn from(e: AvroError) -> Self {
153        match e {
154            AvroError::External(inner) => ArrowError::from_external_error(inner),
155            AvroError::IoError(msg, err) => ArrowError::IoError(msg, err),
156            AvroError::ArrowError(inner) => *inner,
157            other => ArrowError::AvroError(other.to_string()),
158        }
159    }
160}