1use arrow_schema::ArrowError;
21use core::num::TryFromIntError;
22use std::error::Error;
23use std::string::FromUtf8Error;
24use std::{io, str};
25
26#[derive(Debug)]
29#[non_exhaustive]
30pub enum AvroError {
31 General(String),
34 NYI(String),
37 EOF(String),
41 ArrowError(Box<ArrowError>),
44 IndexOutOfBound(usize, usize),
47 InvalidArgument(String),
49 ParseError(String),
51 SchemaError(String),
53 External(Box<dyn Error + Send + Sync>),
55 IoError(String, io::Error),
57 NeedMoreData(usize),
60 NeedMoreDataRange(std::ops::Range<u64>),
63 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}