## Coverage Report

#### Created: 2025-11-17 14:14

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 Avro-related operations.
    50
        AvroError(String),
    51
        /// Error during IO operations.
    52
        IoError(String, std::io::Error),
    53
        /// Error during IPC operations in `arrow-ipc` or `arrow-flight`.
    54
        IpcError(String),
    55
        /// Error indicating that an unexpected or bad argument was passed to a function.
    56
        InvalidArgumentError(String),
    57
        /// Error during Parquet operations.
    58
        ParquetError(String),
    59
        /// Error during import or export to/from the C Data Interface
    60
        CDataInterface(String),
    61
        /// Error when a dictionary key is bigger than the key type
    62
        DictionaryKeyOverflowError,
    63
        /// Error when the run end index in a REE array is bigger than the array length
    64
        RunEndIndexOverflowError,
    65
        /// Error when the offset overflows.
    66
        OffsetOverflowError(usize),
    67
    }
    68
    69
    impl ArrowError {
    70
        /// Wraps an external error in an `ArrowError`.
    71
    0
        pub fn from_external_error(error: Box<dyn Error + Send + Sync>) -> Self {
    72
    0
            Self::ExternalError(error)
    73
    0
        }
    74
    }
    75
    76
    impl From<std::io::Error> for ArrowError {
    77
    0
        fn from(error: std::io::Error) -> Self {
    78
    0
            ArrowError::IoError(error.to_string(), error)
    79
    0
        }
    80
    }
    81
    82
    impl From<std::str::Utf8Error> for ArrowError {
    83
    0
        fn from(error: std::str::Utf8Error) -> Self {
    84
    0
            ArrowError::ParseError(error.to_string())
    85
    0
        }
    86
    }
    87
    88
    impl From<std::string::FromUtf8Error> for ArrowError {
    89
    0
        fn from(error: std::string::FromUtf8Error) -> Self {
    90
    0
            ArrowError::ParseError(error.to_string())
    91
    0
        }
    92
    }
    93
    94
    impl<W: Write> From<std::io::IntoInnerError<W>> for ArrowError {
    95
    0
        fn from(error: std::io::IntoInnerError<W>) -> Self {
    96
    0
            ArrowError::IoError(error.to_string(), error.into())
    97
    0
        }
    98
    }
    99
    100
    impl Display for ArrowError {
    101
    10
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
    102
    10
            match self {
    103
    0
                ArrowError::NotYetImplemented(source) => {
    104
    0
                    write!(f, "Not yet implemented: {}", &source)
    105
                }
    106
    0
                ArrowError::ExternalError(source) => write!(f, "External error: {}", &source),
    107
    0
                ArrowError::CastError(desc) => write!(f, "Cast error: {desc}"),
    108
    0
                ArrowError::MemoryError(desc) => write!(f, "Memory error: {desc}"),
    109
    0
                ArrowError::ParseError(desc) => write!(f, "Parser error: {desc}"),
    110
    0
                ArrowError::SchemaError(desc) => write!(f, "Schema error: {desc}"),
    111
    1
                ArrowError::ComputeError(desc) => write!(f, "Compute error: {desc}"),
    112
    0
                ArrowError::ArithmeticOverflow(desc) => write!(f, "Arithmetic overflow: {desc}"),
    113
    0
                ArrowError::DivideByZero => write!(f, "Divide by zero error"),
    114
    0
                ArrowError::AvroError(desc) => write!(f, "Avro error: {desc}"),
    115
    0
                ArrowError::CsvError(desc) => write!(f, "Csv error: {desc}"),
    116
    0
                ArrowError::JsonError(desc) => write!(f, "Json error: {desc}"),
    117
    0
                ArrowError::IoError(desc, _) => write!(f, "Io error: {desc}"),
    118
    0
                ArrowError::IpcError(desc) => write!(f, "Ipc error: {desc}"),
    119
    9
                ArrowError::InvalidArgumentError(desc) => {
    120
    9
                    write!(f, "Invalid argument error: {desc}")
    121
                }
    122
    0
                ArrowError::ParquetError(desc) => {
    123
    0
                    write!(f, "Parquet argument error: {desc}")
    124
                }
    125
    0
                ArrowError::CDataInterface(desc) => {
    126
    0
                    write!(f, "C Data interface error: {desc}")
    127
                }
    128
                ArrowError::DictionaryKeyOverflowError => {
    129
    0
                    write!(f, "Dictionary key bigger than the key type")
    130
                }
    131
                ArrowError::RunEndIndexOverflowError => {
    132
    0
                    write!(f, "Run end encoded array index overflow error")
    133
                }
    134
    0
                ArrowError::OffsetOverflowError(offset) => {
    135
    0
                    write!(f, "Offset overflow error: {offset}")
    136
                }
    137
            }
    138
    10
        }
    139
    }
    140
    141
    impl Error for ArrowError {
    142
    0
        fn source(&self) -> Option<&(dyn Error + 'static)> {
    143
    0
            match self {
    144
    0
                ArrowError::ExternalError(source) => Some(source.as_ref()),
    145
    0
                ArrowError::IoError(_, source) => Some(source),
    146
    0
                _ => None,
    147
            }
    148
    0
        }
    149
    }
    150
    151
    #[cfg(test)]
    152
    mod test {
    153
        use super::*;
    154
    155
        #[test]
    156
        fn error_source() {
    157
            let e1 = ArrowError::DivideByZero;
    158
            assert!(e1.source().is_none());
    159
    160
            // one level of wrapping
    161
            let e2 = ArrowError::ExternalError(Box::new(e1));
    162
            let source = e2.source().unwrap().downcast_ref::<ArrowError>().unwrap();
    163
            assert!(matches!(source, ArrowError::DivideByZero));
    164
    165
            // two levels of wrapping
    166
            let e3 = ArrowError::ExternalError(Box::new(e2));
    167
            let source = e3
    168
                .source()
    169
                .unwrap()
    170
                .downcast_ref::<ArrowError>()
    171
                .unwrap()
    172
                .source()
    173
                .unwrap()
    174
                .downcast_ref::<ArrowError>()
    175
                .unwrap();
    176
    177
            assert!(matches!(source, ArrowError::DivideByZero));
    178
        }
    179
    }