Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Simplified ArrowError #640

Merged
merged 1 commit into from
Nov 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/array/binary/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ impl<O: Offset, T: AsRef<[u8]>> TryPush<Option<T>> for MutableBinaryArray<O> {
Some(value) => {
let bytes = value.as_ref();

let size = O::from_usize(self.values.len() + bytes.len())
.ok_or(ArrowError::KeyOverflowError)?;
let size =
O::from_usize(self.values.len() + bytes.len()).ok_or(ArrowError::Overflow)?;

self.values.extend_from_slice(bytes);

Expand Down
2 changes: 1 addition & 1 deletion src/array/dictionary/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<K: DictionaryKey, M: MutableArray> MutableDictionaryArray<K, M> {
Ok(false)
}
None => {
let key = K::from_usize(self.map.len()).ok_or(ArrowError::KeyOverflowError)?;
let key = K::from_usize(self.map.len()).ok_or(ArrowError::Overflow)?;
self.map.insert(hash, key);
self.keys.push(Some(key));
Ok(true)
Expand Down
2 changes: 1 addition & 1 deletion src/array/fixed_size_list/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<M: MutableArray> MutableFixedSizeListArray<M> {
#[inline]
fn try_push_valid(&mut self) -> Result<()> {
if self.values.len() % self.size != 0 {
return Err(ArrowError::KeyOverflowError);
return Err(ArrowError::Overflow);
};
if let Some(validity) = &mut self.validity {
validity.push(true)
Expand Down
2 changes: 1 addition & 1 deletion src/array/list/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<O: Offset, M: MutableArray> MutableListArray<O, M> {
/// This is a relatively low level function, prefer `try_push` when you can.
pub fn try_push_valid(&mut self) -> Result<()> {
let size = self.values.len();
let size = O::from_usize(size).ok_or(ArrowError::KeyOverflowError)?; // todo: make this error
let size = O::from_usize(size).ok_or(ArrowError::Overflow)?;
assert!(size >= *self.offsets.last().unwrap());

self.offsets.push(size);
Expand Down
2 changes: 1 addition & 1 deletion src/array/utf8/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ impl<O: Offset, T: AsRef<str>> TryPush<Option<T>> for MutableUtf8Array<O> {
let bytes = value.as_ref().as_bytes();
self.values.extend_from_slice(bytes);

let size = O::from_usize(self.values.len()).ok_or(ArrowError::KeyOverflowError)?;
let size = O::from_usize(self.values.len()).ok_or(ArrowError::Overflow)?;

self.offsets.push(size);

Expand Down
6 changes: 3 additions & 3 deletions src/compute/cast/dictionary_to.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ macro_rules! key_cast {
// Failure to cast keys (because they don't fit in the
// target type) results in NULL values;
if cast_keys.null_count() > $keys.null_count() {
return Err(ArrowError::KeyOverflowError);
return Err(ArrowError::Overflow);
}
Ok(Box::new(DictionaryArray::<$to_type>::from_data(
cast_keys, $values,
Expand Down Expand Up @@ -74,7 +74,7 @@ where
let casted_keys = primitive_to_primitive::<K1, K2>(keys, &K2::DATA_TYPE);

if casted_keys.null_count() > keys.null_count() {
Err(ArrowError::KeyOverflowError)
Err(ArrowError::Overflow)
} else {
Ok(DictionaryArray::from_data(casted_keys, values.clone()))
}
Expand All @@ -94,7 +94,7 @@ where
let casted_keys = primitive_as_primitive::<K1, K2>(keys, &K2::DATA_TYPE);

if casted_keys.null_count() > keys.null_count() {
Err(ArrowError::KeyOverflowError)
Err(ArrowError::Overflow)
} else {
Ok(DictionaryArray::from_data(casted_keys, values.clone()))
}
Expand Down
12 changes: 6 additions & 6 deletions src/datatypes/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl Field {
for (key, from_value) in from_metadata {
if let Some(self_value) = self_metadata.get(key) {
if self_value != from_value {
return Err(ArrowError::Schema(format!(
return Err(ArrowError::InvalidArgumentError(format!(
"Fail to merge field due to conflicting metadata data value for key {}", key),
));
}
Expand All @@ -193,12 +193,12 @@ impl Field {
_ => {}
}
if from.dict_id != self.dict_id {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema Field due to conflicting dict_id".to_string(),
));
}
if from.dict_is_ordered != self.dict_is_ordered {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema Field due to conflicting dict_is_ordered".to_string(),
));
}
Expand All @@ -220,7 +220,7 @@ impl Field {
}
}
_ => {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema Field due to conflicting datatype".to_string(),
));
}
Expand All @@ -241,7 +241,7 @@ impl Field {
}
}
_ => {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema Field due to conflicting datatype".to_string(),
));
}
Expand Down Expand Up @@ -279,7 +279,7 @@ impl Field {
| DataType::Map(_, _)
| DataType::Decimal(_, _) => {
if self.data_type != from.data_type {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema Field due to conflicting datatype".to_string(),
));
}
Expand Down
2 changes: 1 addition & 1 deletion src/datatypes/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Schema {
// merge metadata
if let Some(old_val) = merged.metadata.get(&key) {
if old_val != &value {
return Err(ArrowError::Schema(
return Err(ArrowError::InvalidArgumentError(
"Fail to merge schema due to conflicting metadata.".to_string(),
));
}
Expand Down
38 changes: 10 additions & 28 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,23 @@ use std::error::Error;

/// Enum with all errors in this crate.
#[derive(Debug)]
#[non_exhaustive]
pub enum ArrowError {
/// Returned when functionality is not yet available.
NotYetImplemented(String),
/// Triggered by an external error, such as CSV, serde, chrono.
/// Wrapper for an error triggered by a dependency
External(String, Box<dyn Error + Send + Sync>),
/// Error associated with incompatible schemas.
Schema(String),
/// Errors associated with IO
/// Wrapper for IO errors
Io(std::io::Error),
/// When an invalid argument is passed to a function.
InvalidArgumentError(String),
/// Error during import or export to/from C Data Interface
Ffi(String),
/// Error during import or export to/from IPC
Ipc(String),
/// Error during import or export to/from a format
ExternalFormat(String),
/// Whenever pushing to a container fails because it does not support more entries.
/// (e.g. maximum size of the keys of a dictionary overflowed)
KeyOverflowError,
/// Error during arithmetic operation. Normally returned
/// during checked operations
ArithmeticError(String),
/// Any other error.
Other(String),
/// The solution is usually to use a higher-capacity container-backing type.
Overflow,
/// Whenever incoming data from the C data interface, IPC or Flight does not fulfil the Arrow specification.
OutOfSpec(String),
}

impl ArrowError {
Expand Down Expand Up @@ -66,27 +58,17 @@ impl Display for ArrowError {
ArrowError::External(message, source) => {
write!(f, "External error{}: {}", message, &source)
}
ArrowError::Schema(desc) => write!(f, "Schema error: {}", desc),
ArrowError::Io(desc) => write!(f, "Io error: {}", desc),
ArrowError::InvalidArgumentError(desc) => {
write!(f, "Invalid argument error: {}", desc)
}
ArrowError::Ffi(desc) => {
write!(f, "FFI error: {}", desc)
}
ArrowError::Ipc(desc) => {
write!(f, "IPC error: {}", desc)
}
ArrowError::ExternalFormat(desc) => {
write!(f, "External format error: {}", desc)
}
ArrowError::KeyOverflowError => {
write!(f, "Dictionary key bigger than the key type")
}
ArrowError::ArithmeticError(desc) => {
write!(f, "Arithmetic error: {}", desc)
ArrowError::Overflow => {
write!(f, "Operation overflew the backing container.")
}
ArrowError::Other(message) => {
ArrowError::OutOfSpec(message) => {
write!(f, "{}", message)
}
}
Expand Down
14 changes: 10 additions & 4 deletions src/ffi/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ unsafe fn create_buffer<T: NativeType>(
index: usize,
) -> Result<Buffer<T>> {
if array.buffers.is_null() {
return Err(ArrowError::Ffi("The array buffers are null".to_string()));
return Err(ArrowError::OutOfSpec(
"The array buffers are null".to_string(),
));
}

let buffers = array.buffers as *mut *const u8;
Expand All @@ -197,7 +199,9 @@ unsafe fn create_buffer<T: NativeType>(
let offset = buffer_offset(array, data_type, index);
let bytes = ptr
.map(|ptr| Bytes::new(ptr, len, deallocation))
.ok_or_else(|| ArrowError::Ffi(format!("The buffer at position {} is null", index)))?;
.ok_or_else(|| {
ArrowError::OutOfSpec(format!("The buffer at position {} is null", index))
})?;

Ok(Buffer::from_bytes(bytes).slice(offset, len - offset))
}
Expand All @@ -215,7 +219,9 @@ unsafe fn create_bitmap(
index: usize,
) -> Result<Bitmap> {
if array.buffers.is_null() {
return Err(ArrowError::Ffi("The array buffers are null".to_string()));
return Err(ArrowError::OutOfSpec(
"The array buffers are null".to_string(),
));
}
let len = array.length as usize;
let offset = array.offset as usize;
Expand All @@ -229,7 +235,7 @@ unsafe fn create_bitmap(
let bytes = ptr
.map(|ptr| Bytes::new(ptr, bytes_len, deallocation))
.ok_or_else(|| {
ArrowError::Ffi(format!(
ArrowError::OutOfSpec(format!(
"The buffer {} is a null pointer and cannot be interpreted as a bitmap",
index
))
Expand Down
36 changes: 21 additions & 15 deletions src/ffi/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ fn to_integer_type(format: &str) -> Result<IntegerType> {
"l" => Int64,
"L" => UInt64,
_ => {
return Err(ArrowError::Ffi(
return Err(ArrowError::OutOfSpec(
"Dictionary indices can only be integers".to_string(),
))
}
Expand Down Expand Up @@ -312,36 +312,40 @@ unsafe fn to_data_type(schema: &Ffi_ArrowSchema) -> Result<DataType> {
} else if parts.len() == 2 && parts[0] == "tsn" {
DataType::Timestamp(TimeUnit::Nanosecond, Some(parts[1].to_string()))
} else if parts.len() == 2 && parts[0] == "w" {
let size = parts[1]
.parse::<usize>()
.map_err(|_| ArrowError::Ffi("size is not a valid integer".to_string()))?;
let size = parts[1].parse::<usize>().map_err(|_| {
ArrowError::OutOfSpec("size is not a valid integer".to_string())
})?;
DataType::FixedSizeBinary(size)
} else if parts.len() == 2 && parts[0] == "+w" {
let size = parts[1]
.parse::<usize>()
.map_err(|_| ArrowError::Ffi("size is not a valid integer".to_string()))?;
let size = parts[1].parse::<usize>().map_err(|_| {
ArrowError::OutOfSpec("size is not a valid integer".to_string())
})?;
let child = to_field(schema.child(0))?;
DataType::FixedSizeList(Box::new(child), size)
} else if parts.len() == 2 && parts[0] == "d" {
let parts = parts[1].split(',').collect::<Vec<_>>();
if parts.len() < 2 || parts.len() > 3 {
return Err(ArrowError::Ffi(
return Err(ArrowError::OutOfSpec(
"Decimal must contain 2 or 3 comma-separated values".to_string(),
));
};
if parts.len() == 3 {
let bit_width = parts[0].parse::<usize>().map_err(|_| {
ArrowError::Ffi("Decimal bit width is not a valid integer".to_string())
ArrowError::OutOfSpec(
"Decimal bit width is not a valid integer".to_string(),
)
})?;
if bit_width != 128 {
return Err(ArrowError::Ffi("Decimal256 is not supported".to_string()));
return Err(ArrowError::OutOfSpec(
"Decimal256 is not supported".to_string(),
));
}
}
let precision = parts[0].parse::<usize>().map_err(|_| {
ArrowError::Ffi("Decimal precision is not a valid integer".to_string())
ArrowError::OutOfSpec("Decimal precision is not a valid integer".to_string())
})?;
let scale = parts[1].parse::<usize>().map_err(|_| {
ArrowError::Ffi("Decimal scale is not a valid integer".to_string())
ArrowError::OutOfSpec("Decimal scale is not a valid integer".to_string())
})?;
DataType::Decimal(precision, scale)
} else if !parts.is_empty() && ((parts[0] == "+us") || (parts[0] == "+ud")) {
Expand All @@ -351,7 +355,9 @@ unsafe fn to_data_type(schema: &Ffi_ArrowSchema) -> Result<DataType> {
.split(',')
.map(|x| {
x.parse::<i32>().map_err(|_| {
ArrowError::Ffi("Union type id is not a valid integer".to_string())
ArrowError::OutOfSpec(
"Union type id is not a valid integer".to_string(),
)
})
})
.collect::<Result<Vec<_>>>()?;
Expand All @@ -360,7 +366,7 @@ unsafe fn to_data_type(schema: &Ffi_ArrowSchema) -> Result<DataType> {
.collect::<Result<Vec<_>>>()?;
DataType::Union(fields, Some(type_ids), mode)
} else {
return Err(ArrowError::Ffi(format!(
return Err(ArrowError::OutOfSpec(format!(
"The datatype \"{}\" is still not supported in Rust implementation",
other
)));
Expand Down Expand Up @@ -456,7 +462,7 @@ pub(super) fn get_field_child(field: &Field, index: usize) -> Result<Field> {
(0, DataType::Map(field, _)) => Ok(field.as_ref().clone()),
(index, DataType::Struct(fields)) => Ok(fields[index].clone()),
(index, DataType::Union(fields, _, _)) => Ok(fields[index].clone()),
(child, data_type) => Err(ArrowError::Ffi(format!(
(child, data_type) => Err(ArrowError::OutOfSpec(format!(
"Requested child {} to type {:?} that has no such child",
child, data_type
))),
Expand Down
4 changes: 2 additions & 2 deletions src/io/avro/read/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ fn decompress_block(
#[cfg(feature = "io_avro_compression")]
Some(Compression::Snappy) => {
let len = snap::raw::decompress_len(&block[..block.len() - 4])
.map_err(|_| ArrowError::Other("Failed to decompress snap".to_string()))?;
.map_err(|_| ArrowError::ExternalFormat("Failed to decompress snap".to_string()))?;
decompress.clear();
decompress.resize(len, 0);
snap::raw::Decoder::new()
.decompress(&block[..block.len() - 4], decompress)
.map_err(|_| ArrowError::Other("Failed to decompress snap".to_string()))?;
.map_err(|_| ArrowError::ExternalFormat("Failed to decompress snap".to_string()))?;
Ok(false)
}
#[cfg(not(feature = "io_avro_compression"))]
Expand Down
2 changes: 1 addition & 1 deletion src/io/avro/read/nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<O: Offset> DynMutableListArray<O> {
#[inline]
pub fn try_push_valid(&mut self) -> Result<()> {
let size = self.values.len();
let size = O::from_usize(size).ok_or(ArrowError::KeyOverflowError)?; // todo: make this error
let size = O::from_usize(size).ok_or(ArrowError::Overflow)?;
assert!(size >= *self.offsets.last().unwrap());

self.offsets.push(size);
Expand Down
Loading