## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-schema/src/error.rs

    Line
    Count
    Source
    1
    // Licensed to the Apache Software Foundation (ASF) under one
    2
    // or more contributor license agreements.  See the NOTICE file
    3
    // distributed with this work for additional information
    4
    // regarding copyright ownership.  The ASF licenses this file
    5
    // to you under the Apache License, Version 2.0 (the
    6
    // "License"); you may not use this file except in compliance
    7
    // with the License.  You may obtain a copy of the License at
    8
    //
    9
    //   http://www.apache.org/licenses/LICENSE-2.0
    10
    //
    11
    // Unless required by applicable law or agreed to in writing,
    12
    // software distributed under the License is distributed on an
    13
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14
    // KIND, either express or implied.  See the License for the
    15
    // specific language governing permissions and limitations
    16
    // under the License.
    17
    18
    //! Defines `ArrowError` for representing failures in various Arrow operations.
    19
    use std::fmt::{Debug, Display, Formatter};
    20
    use std::io::Write;
    21
    22
    use std::error::Error;
    23
    24
    /// Many different operations in the `arrow` crate return this error type.
    25
    #[derive(Debug)]
    26
    pub enum ArrowError {
    27
        /// Returned when functionality is not yet available.
    28
        NotYetImplemented(String),
    29
        /// Wraps an external error.
    30
        ExternalError(Box<dyn Error + Send + Sync>),
    31
        /// Error during casting from one type to another.
    32
        CastError(String),
    33
        /// Memory or buffer error.
    34
        MemoryError(String),
    35
        /// Error during parsing from a string.
    36
        ParseError(String),
    37
        /// Error during schema-related operations.
    38
        SchemaError(String),
    39
        /// Error during computation.
    40
        ComputeError(String),
    41
        /// Error during division by zero.
    42
        DivideByZero,
    43
        /// Error when an arithmetic operation overflows.
    44
        ArithmeticOverflow(String),
    45
        /// Error during CSV-related operations.
    46
        CsvError(String),
    47
        /// Error during JSON-related operations.
    48
        JsonError(String),
    49
        /// Error during IO operations.
    50
        IoError(String, std::io::Error),
    51
        /// Error during IPC operations in `arrow-ipc` or `arrow-flight`.
    52
        IpcError(String),
    53
        /// Error indicating that an unexpected or bad argument was passed to a function.
    54
        InvalidArgumentError(String),
    55
        /// Error during Parquet operations.
    56
        ParquetError(String),
    57
        /// Error during import or export to/from the C Data Interface
    58
        CDataInterface(String),
    59
        /// Error when a dictionary key is bigger than the key type
    60
        DictionaryKeyOverflowError,
    61
        /// Error when the run end index in a REE array is bigger than the array length
    62
        RunEndIndexOverflowError,
    63
        /// Error when the offset overflows.
    64
        OffsetOverflowError(usize),
    65
    }
    66
    67
    impl ArrowError {
    68
        /// Wraps an external error in an `ArrowError`.
    69
    0
        pub fn from_external_error(error: Box<dyn Error + Send + Sync>) -> Self {
    70
    0
            Self::ExternalError(error)
    71
    0
        }
    72
    }
    73
    74
    impl From<std::io::Error> for ArrowError {
    75
    0
        fn from(error: std::io::Error) -> Self {
    76
    0
            ArrowError::IoError(error.to_string(), error)
    77
    0
        }
    78
    }
    79
    80
    impl From<std::str::Utf8Error> for ArrowError {
    81
    0
        fn from(error: std::str::Utf8Error) -> Self {
    82
    0
            ArrowError::ParseError(error.to_string())
    83
    0
        }
    84
    }
    85
    86
    impl From<std::string::FromUtf8Error> for ArrowError {
    87
    0
        fn from(error: std::string::FromUtf8Error) -> Self {
    88
    0
            ArrowError::ParseError(error.to_string())
    89
    0
        }
    90
    }
    91
    92
    impl<W: Write> From<std::io::IntoInnerError<W>> for ArrowError {
    93
    0
        fn from(error: std::io::IntoInnerError<W>) -> Self {
    94
    0
            ArrowError::IoError(error.to_string(), error.into())
    95
    0
        }
    96
    }
    97
    98
    impl Display for ArrowError {
    99
    8
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
    100
    8
            match self {
    101
    1
                ArrowError::NotYetImplemented(source) => {
    102
    1
                    write!(f, "Not yet implemented: {}", &source)
    103
                }
    104
    0
                ArrowError::ExternalError(source) => write!(f, "External error: {}", &source),
    105
    0
                ArrowError::CastError(desc) => write!(f, "Cast error: {desc}"),
    106
    0
                ArrowError::MemoryError(desc) => write!(f, "Memory error: {desc}"),
    107
    5
                ArrowError::ParseError(desc) => write!(f, "Parser error: {desc}"),
    108
    2
                ArrowError::SchemaError(desc) => write!(f, "Schema error: {desc}"),
    109
    0
                ArrowError::ComputeError(desc) => write!(f, "Compute error: {desc}"),
    110
    0
                ArrowError::ArithmeticOverflow(desc) => write!(f, "Arithmetic overflow: {desc}"),
    111
    0
                ArrowError::DivideByZero => write!(f, "Divide by zero error"),
    112
    0
                ArrowError::CsvError(desc) => write!(f, "Csv error: {desc}"),
    113
    0
                ArrowError::JsonError(desc) => write!(f, "Json error: {desc}"),
    114
    0
                ArrowError::IoError(desc, _) => write!(f, "Io error: {desc}"),
    115
    0
                ArrowError::IpcError(desc) => write!(f, "Ipc error: {desc}"),
    116
    0
                ArrowError::InvalidArgumentError(desc) => {
    117
    0
                    write!(f, "Invalid argument error: {desc}")
    118
                }
    119
    0
                ArrowError::ParquetError(desc) => {
    120
    0
                    write!(f, "Parquet argument error: {desc}")
    121
                }
    122
    0
                ArrowError::CDataInterface(desc) => {
    123
    0
                    write!(f, "C Data interface error: {desc}")
    124
                }
    125
                ArrowError::DictionaryKeyOverflowError => {
    126
    0
                    write!(f, "Dictionary key bigger than the key type")
    127
                }
    128
                ArrowError::RunEndIndexOverflowError => {
    129
    0
                    write!(f, "Run end encoded array index overflow error")
    130
                }
    131
    0
                ArrowError::OffsetOverflowError(offset) => {
    132
    0
                    write!(f, "Offset overflow error: {offset}")
    133
                }
    134
            }
    135
    8
        }
    136
    }
    137
    138
    impl Error for ArrowError {
    139
    0
        fn source(&self) -> Option<&(dyn Error + 'static)> {
    140
    0
            match self {
    141
    0
                ArrowError::ExternalError(source) => Some(source.as_ref()),
    142
    0
                ArrowError::IoError(_, source) => Some(source),
    143
    0
                _ => None,
    144
            }
    145
    0
        }
    146
    }
    147
    148
    #[cfg(test)]
    149
    mod test {
    150
        use super::*;
    151
    152
        #[test]
    153
        fn error_source() {
    154
            let e1 = ArrowError::DivideByZero;
    155
            assert!(e1.source().is_none());
    156
    157
            // one level of wrapping
    158
            let e2 = ArrowError::ExternalError(Box::new(e1));
    159
            let source = e2.source().unwrap().downcast_ref::<ArrowError>().unwrap();
    160
            assert!(matches!(source, ArrowError::DivideByZero));
    161
    162
            // two levels of wrapping
    163
            let e3 = ArrowError::ExternalError(Box::new(e2));
    164
            let source = e3
    165
                .source()
    166
                .unwrap()
    167
                .downcast_ref::<ArrowError>()
    168
                .unwrap()
    169
                .source()
    170
                .unwrap()
    171
                .downcast_ref::<ArrowError>()
    172
                .unwrap();
    173
    174
            assert!(matches!(source, ArrowError::DivideByZero));
    175
        }
    176
    }