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

Commit

Permalink
Simplified errors (#640)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao committed Nov 27, 2021
1 parent f1ff358 commit f869146
Show file tree
Hide file tree
Showing 32 changed files with 187 additions and 178 deletions.
4 changes: 2 additions & 2 deletions src/array/binary/mutable.rs
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
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
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
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
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
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
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
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
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
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
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
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
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

0 comments on commit f869146

Please sign in to comment.