Skip to content

Commit

Permalink
Improve Error handling (#2832)
Browse files Browse the repository at this point in the history
* fix not found panic

* make error type simpler and smaller

* python exceptions
  • Loading branch information
ritchie46 committed Mar 5, 2022
1 parent da4b3ab commit cdcc9a4
Show file tree
Hide file tree
Showing 61 changed files with 584 additions and 370 deletions.
2 changes: 1 addition & 1 deletion polars/polars-arrow/src/kernels/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ where
idx.into_iter().try_for_each::<_, Result<_>>(|idx| {
let val = mut_slice
.get_mut(idx)
.ok_or_else(|| PolarsError::OutOfBounds("idx is out of bounds".into()))?;
.ok_or_else(|| PolarsError::ComputeError("idx is out of bounds".into()))?;
*val = set_value;
Ok(())
})?;
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ where
if self.chunks.len() == 1 && !self.chunks[0].has_validity() {
Ok(self.downcast_iter().next().map(|arr| arr.values()).unwrap())
} else {
Err(PolarsError::NoSlice)
Err(PolarsError::ComputeError("cannot take slice".into()))
}
}

Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/ndarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl ListChunked {
N: PolarsNumericType,
{
if self.null_count() != 0 {
Err(PolarsError::HasNullValues(
Err(PolarsError::ComputeError(
"Creation of ndarray with null values is not supported.".into(),
))
} else {
Expand Down Expand Up @@ -127,7 +127,7 @@ impl DataFrame {

columns.par_iter().enumerate().map(|(col_idx, s)| {
if s.null_count() != 0 {
return Err(PolarsError::HasNullValues(
return Err(PolarsError::ComputeError(
"Creation of ndarray with null values is not supported. Consider using floats and NaNs".into(),
));
}
Expand Down
6 changes: 3 additions & 3 deletions polars/polars-core/src/chunked_array/ops/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ where
{
fn quantile(&self, quantile: f64, interpol: QuantileInterpolOptions) -> Result<Option<f64>> {
if !(0.0..=1.0).contains(&quantile) {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"quantile should be between 0.0 and 1.0".into(),
));
}
Expand Down Expand Up @@ -239,7 +239,7 @@ where
impl ChunkQuantile<f32> for Float32Chunked {
fn quantile(&self, quantile: f64, interpol: QuantileInterpolOptions) -> Result<Option<f32>> {
if !(0.0..=1.0).contains(&quantile) {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"quantile should be between 0.0 and 1.0".into(),
));
}
Expand Down Expand Up @@ -309,7 +309,7 @@ impl ChunkQuantile<f32> for Float32Chunked {
impl ChunkQuantile<f64> for Float64Chunked {
fn quantile(&self, quantile: f64, interpol: QuantileInterpolOptions) -> Result<Option<f64>> {
if !(0.0..=1.0).contains(&quantile) {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"quantile should be between 0.0 and 1.0".into(),
));
}
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/ops/rolling_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ mod inner_mod {
/// utility
fn check_input(window_size: usize, min_periods: usize) -> Result<()> {
if min_periods > window_size {
Err(PolarsError::ValueError(
Err(PolarsError::ComputeError(
"`windows_size` should be >= `min_periods`".into(),
))
} else {
Expand Down
6 changes: 3 additions & 3 deletions polars/polars-core/src/chunked_array/ops/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ macro_rules! impl_set_at_idx_with {

while let Some(current_idx) = idx_iter.next() {
if current_idx > $self.len() {
return Err(PolarsError::OutOfBounds(
return Err(PolarsError::ComputeError(
format!(
"index: {} outside of ChunkedArray with length: {}",
current_idx,
Expand Down Expand Up @@ -80,7 +80,7 @@ where

idx.into_iter().try_for_each::<_, Result<_>>(|idx| {
let val = data.get_mut(idx).ok_or_else(|| {
PolarsError::OutOfBounds(
PolarsError::ComputeError(
format!("{} out of bounds on array of length: {}", idx, self.len())
.into(),
)
Expand Down Expand Up @@ -241,7 +241,7 @@ impl<'a> ChunkSet<'a, &'a str, String> for Utf8Chunked {

for current_idx in idx_iter {
if current_idx > self.len() {
return Err(PolarsError::OutOfBounds(
return Err(PolarsError::ComputeError(
format!(
"index: {} outside of ChunkedArray with length: {}",
current_idx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) fn args_validate<T: PolarsDataType>(
assert_eq!(ca.len(), s.len());
}
if other.len() != (reverse.len() - 1) {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
format!(
"The amount of ordering booleans: {} does not match that no. of Series: {}",
reverse.len(),
Expand Down
6 changes: 3 additions & 3 deletions polars/polars-core/src/chunked_array/ops/take/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ where
if inbounds {
Ok(())
} else {
Err(PolarsError::OutOfBounds(
Err(PolarsError::ComputeError(
"take indices are out of bounds".into(),
))
}
Expand Down Expand Up @@ -86,7 +86,7 @@ where
if inbounds {
Ok(())
} else {
Err(PolarsError::OutOfBounds(
Err(PolarsError::ComputeError(
"take indices are out of bounds".into(),
))
}
Expand Down Expand Up @@ -142,7 +142,7 @@ where
if inbounds {
Ok(())
} else {
Err(PolarsError::OutOfBounds(
Err(PolarsError::ComputeError(
"take indices are out of bounds".into(),
))
}
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ where
pub fn rand_normal(name: &str, length: usize, mean: f64, std_dev: f64) -> Result<Self> {
let normal = match Normal::new(mean, std_dev) {
Ok(dist) => dist,
Err(e) => return Err(PolarsError::RandError(format!("{:?}", e))),
Err(e) => return Err(PolarsError::ComputeError(format!("{:?}", e).into())),
};
let mut builder = PrimitiveChunkedBuilder::<T>::new(name, length);
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -189,7 +189,7 @@ impl BooleanChunked {
pub fn rand_bernoulli(name: &str, length: usize, p: f64) -> Result<Self> {
let dist = match Bernoulli::new(p) {
Ok(dist) => dist,
Err(e) => return Err(PolarsError::RandError(format!("{:?}", e))),
Err(e) => return Err(PolarsError::ComputeError(format!("{:?}", e).into())),
};
let mut rng = rand::thread_rng();
let mut builder = BooleanChunkedBuilder::new(name, length);
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/strings/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Utf8Chunked {
});

if strict.unwrap_or(false) && (ca.null_count() != self.null_count()) {
Err(PolarsError::ValueError("Unable to decode inputs".into()))
Err(PolarsError::ComputeError("Unable to decode inputs".into()))
} else {
Ok(ca)
}
Expand All @@ -41,7 +41,7 @@ impl Utf8Chunked {
});

if strict.unwrap_or(false) && (ca.null_count() != self.null_count()) {
Err(PolarsError::ValueError("Unable to decode inputs".into()))
Err(PolarsError::ComputeError("Unable to decode inputs".into()))
} else {
Ok(ca)
}
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/strings/json_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl Utf8Chunked {
pub fn json_path_match(&self, json_path: &str) -> Result<Utf8Chunked> {
match Compiled::compile(json_path) {
Ok(pat) => Ok(self.apply_on_opt(|opt_s| opt_s.and_then(|s| extract_json(&pat, s)))),
Err(e) => Err(PolarsError::ValueError(
Err(e) => Err(PolarsError::ComputeError(
format!("error compiling JSONpath expression {:?}", e).into(),
)),
}
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/temporal/utf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Utf8Chunked {
let idx = match self.first_non_null() {
Some(idx) => idx,
None => {
return Err(PolarsError::HasNullValues(
return Err(PolarsError::ComputeError(
"Cannot determine date parsing format, all values are null".into(),
))
}
Expand Down
52 changes: 27 additions & 25 deletions polars/polars-core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Error;
use std::borrow::Cow;
use thiserror::Error as ThisError;

Expand All @@ -6,9 +7,7 @@ type ErrString = Cow<'static, str>;
#[derive(Debug, ThisError)]
pub enum PolarsError {
#[error(transparent)]
PolarsArrowError(#[from] polars_arrow::error::PolarsError),
#[error(transparent)]
ArrowError(#[from] arrow::error::ArrowError),
ArrowError(Box<ArrowError>),
#[error("Invalid operation {0}")]
InvalidOperation(ErrString),
#[error("Data types don't match: {0}")]
Expand All @@ -19,34 +18,37 @@ pub enum PolarsError {
ShapeMisMatch(ErrString),
#[error("{0}")]
ComputeError(ErrString),
#[error("Out of bounds: {0}")]
OutOfBounds(ErrString),
#[error("Not contiguous or null values")]
NoSlice,
#[error("Such empty...: {0}")]
NoData(ErrString),
#[error("Invalid value: {0}")]
ValueError(ErrString),
#[error("Memory should be 64 byte aligned")]
MemoryNotAligned,
#[cfg(feature = "random")]
#[error("{0}")]
RandError(String),
#[error("This operation requires data without Null values")]
HasNullValues(ErrString),
#[error("{0}")]
UnknownSchema(ErrString),
#[error(transparent)]
Various(#[from] anyhow::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
#[cfg(any(feature = "strings", feature = "temporal"))]
Regex(#[from] regex::Error),
#[error("DuplicateError: {0}")]
Duplicate(ErrString),
#[error("implementation error; this should not have happened.")]
ImplementationError,
}

impl From<ArrowError> for PolarsError {
fn from(err: ArrowError) -> Self {
Self::ArrowError(Box::new(err))
}
}

impl From<anyhow::Error> for PolarsError {
fn from(err: Error) -> Self {
PolarsError::ComputeError(format!("{:?}", err).into())
}
}

impl From<polars_arrow::error::PolarsError> for PolarsError {
fn from(err: polars_arrow::error::PolarsError) -> Self {
PolarsError::ComputeError(format!("{:?}", err).into())
}
}

#[cfg(any(feature = "strings", feature = "temporal"))]
impl From<regex::Error> for PolarsError {
fn from(err: regex::Error) -> Self {
PolarsError::ComputeError(format!("regex error: {:?}", err).into())
}
}

pub type Result<T> = std::result::Result<T, PolarsError>;
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/frame/asof_join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct AsOfOptions {

fn check_asof_columns(a: &Series, b: &Series) -> Result<()> {
if a.dtype() != b.dtype() {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
format!(
"keys used in asof-join must have equal dtypes. We got: left: {:?}\tright: {:?}",
a.dtype(),
Expand Down Expand Up @@ -58,7 +58,7 @@ where
let other = self.unpack_series_matching_type(other)?;

if self.null_count() > 0 || other.null_count() > 0 {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"asof join must not have null values in 'on' arguments".into(),
));
}
Expand Down
8 changes: 4 additions & 4 deletions polars/polars-core/src/frame/hash_join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) fn check_categorical_src(l: &DataType, r: &DataType) -> Result<()> {
match (l, r) {
(DataType::Categorical(Some(l)), DataType::Categorical(Some(r))) => {
if !l.same_src(&*r) {
return Err(PolarsError::ValueError("joins/or comparisons on categorical dtypes can only happen if they are created under the same global string cache".into()));
return Err(PolarsError::ComputeError("joins/or comparisons on categorical dtypes can only happen if they are created under the same global string cache".into()));
}
Ok(())
}
Expand Down Expand Up @@ -1059,7 +1059,7 @@ impl DataFrame {
suffix: Option<String>,
) -> Result<DataFrame> {
if selected_right.len() != selected_left.len() {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"the number of columns given as join key should be equal".into(),
));
}
Expand All @@ -1068,7 +1068,7 @@ impl DataFrame {
.zip(&selected_right)
.any(|(l, r)| l.dtype() != r.dtype())
{
return Err(PolarsError::ValueError("the dtype of the join keys don't match. first cast your columns to the correct dtype".into()));
return Err(PolarsError::ComputeError("the dtype of the join keys don't match. first cast your columns to the correct dtype".into()));
}

#[cfg(feature = "dtype-categorical")]
Expand Down Expand Up @@ -1208,7 +1208,7 @@ impl DataFrame {
self.finish_join(df_left, df_right, suffix)
}
#[cfg(feature = "asof_join")]
JoinType::AsOf(_) => Err(PolarsError::ValueError(
JoinType::AsOf(_) => Err(PolarsError::ComputeError(
"asof join not supported for join on multiple keys".into(),
)),
JoinType::Cross => {
Expand Down
6 changes: 3 additions & 3 deletions polars/polars-core/src/frame/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ impl DataFrame {
).into()));
};
if idx >= self.width() {
return Err(PolarsError::OutOfBounds(
return Err(PolarsError::ComputeError(
format!(
"Column index: {} outside of DataFrame with {} columns",
idx,
Expand Down Expand Up @@ -1840,7 +1840,7 @@ impl DataFrame {
let df_height = self.height();
let width = self.width();
let col = self.columns.get_mut(idx).ok_or_else(|| {
PolarsError::OutOfBounds(
PolarsError::ComputeError(
format!(
"Column index: {} outside of DataFrame with {} columns",
idx, width
Expand Down Expand Up @@ -1925,7 +1925,7 @@ impl DataFrame {
{
let width = self.width();
let col = self.columns.get_mut(idx).ok_or_else(|| {
PolarsError::OutOfBounds(
PolarsError::ComputeError(
format!(
"Column index: {} outside of DataFrame with {} columns",
idx, width
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/frame/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl DataFrame {
.iter_dtypes()
.any(|dtype| matches!(dtype, DataType::Null));
if has_nulls {
return Err(PolarsError::HasNullValues(
return Err(PolarsError::ComputeError(
"Could not infer row types, because of the null values".into(),
));
}
Expand Down Expand Up @@ -395,7 +395,7 @@ impl AnyValueBuffer {

pub(crate) fn add_falible(&mut self, val: &AnyValue) -> Result<()> {
self.add(val.clone()).ok_or_else(|| {
PolarsError::ValueError(format!("Could not append {:?} to builder; make sure that all rows have the same schema.", val).into())
PolarsError::ComputeError(format!("Could not append {:?} to builder; make sure that all rows have the same schema.", val).into())
})
}

Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ where
/// be used and so on.
pub fn argsort_by(by: &[Series], reverse: &[bool]) -> Result<IdxCa> {
if by.len() != reverse.len() {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
format!(
"The amount of ordering booleans: {} does not match amount of Series: {}",
reverse.len(),
Expand Down Expand Up @@ -149,7 +149,7 @@ pub fn concat_str(s: &[Series], delimiter: &str) -> Result<Utf8Chunked> {
.collect::<Result<Vec<_>>>()?;

if !s.iter().all(|s| s.len() == 1 || s.len() == len) {
return Err(PolarsError::ValueError(
return Err(PolarsError::ComputeError(
"all series in concat_str function should have equal length or unit length".into(),
));
}
Expand Down

0 comments on commit cdcc9a4

Please sign in to comment.