Skip to main content

runlength_arrow/
error.rs

1use std::fmt;
2
3use arrow_schema::{ArrowError, DataType};
4
5/// Errors from Arrow-backed sequences.
6#[derive(Debug)]
7pub enum Error {
8    /// An error from the core crate, such as invalid runs or unequal lengths.
9    Core(runlength::Error),
10    /// An error from an Arrow kernel, such as mismatched types or overflow.
11    Arrow(ArrowError),
12    /// A fill value was not a single value of the right type.
13    InvalidFill {
14        expected: DataType,
15        actual: DataType,
16        len: usize,
17    },
18    /// An operation returned a different number of values than it was given.
19    WrongLength { expected: usize, actual: usize },
20    /// Two batches have keys with different column names or types.
21    KeySchemaMismatch,
22    /// The values have a type this operation does not support.
23    UnsupportedType(DataType),
24    /// The values contain nulls where they are not allowed.
25    UnexpectedNulls,
26    /// An aggregation needs values but none were given.
27    MissingValues,
28    /// An operation needs at least one input but was given none.
29    NoInputs,
30    /// An operation failed for the key at `position` in the output.
31    InKey { position: usize, source: Box<Error> },
32}
33
34impl Error {
35    pub(crate) fn in_key(self, position: usize) -> Self {
36        Error::InKey {
37            position,
38            source: Box::new(self),
39        }
40    }
41}
42
43impl fmt::Display for Error {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        match self {
46            Error::Core(e) => write!(f, "{e}"),
47            Error::Arrow(e) => write!(f, "{e}"),
48            Error::InvalidFill {
49                expected,
50                actual,
51                len,
52            } => write!(
53                f,
54                "fill must be one value of type {expected}, got {len} value(s) of type {actual}"
55            ),
56            Error::WrongLength { expected, actual } => write!(
57                f,
58                "operation returned {actual} values for {expected} segments"
59            ),
60            Error::KeySchemaMismatch => {
61                write!(f, "the batches' key columns have different names or types")
62            }
63            Error::UnsupportedType(t) => write!(f, "unsupported value type {t}"),
64            Error::UnexpectedNulls => write!(f, "values must not contain nulls"),
65            Error::MissingValues => write!(f, "this aggregation needs values"),
66            Error::NoInputs => write!(f, "this operation needs at least one input"),
67            Error::InKey { position, source } => {
68                write!(f, "key at output position {position}: {source}")
69            }
70        }
71    }
72}
73
74impl std::error::Error for Error {
75    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76        match self {
77            Error::Core(e) => Some(e),
78            Error::Arrow(e) => Some(e),
79            Error::InKey { source, .. } => Some(source.as_ref()),
80            _ => None,
81        }
82    }
83}
84
85impl From<runlength::Error> for Error {
86    fn from(e: runlength::Error) -> Self {
87        Error::Core(e)
88    }
89}
90
91impl From<ArrowError> for Error {
92    fn from(e: ArrowError) -> Self {
93        Error::Arrow(e)
94    }
95}
96
97pub type Result<T> = std::result::Result<T, Error>;