feature_factory/
exceptions.rs

1//! ## Custom Errors for Feature Factory
2//!
3//! This module defines custom error types for the Feature Factory library.
4//! It uses the `thiserror` crate to derive the `Error` trait for custom error types.
5//! The `FeatureFactoryError` enum includes variants representing different error scenarios
6//! encountered throughout the library, making error handling straightforward and clear.
7//!
8//! The `FeatureFactoryResult` type alias simplifies error handling by providing a convenient
9//! alias for results returned by the library.
10//!
11//! ### Example
12//!
13//! ```rust
14//! use feature_factory::exceptions::{FeatureFactoryError, FeatureFactoryResult};
15//!
16//! fn load_data() -> FeatureFactoryResult<()> {
17//!     Err(FeatureFactoryError::NotImplemented("CSV loading".into()))
18//! }
19//! ```
20
21use thiserror::Error;
22
23/// Errors specific to the Feature Factory library.
24#[derive(Debug, Error)]
25pub enum FeatureFactoryError {
26    /// Wraps underlying I/O errors.
27    #[error("I/O error: {0}")]
28    IoError(#[from] std::io::Error),
29
30    /// Wraps errors from DataFusion.
31    #[error("DataFusion error: {0}")]
32    DataFusionError(#[from] datafusion::error::DataFusionError),
33
34    /// Wraps errors from Arrow.
35    #[error("Arrow error: {0}")]
36    ArrowError(#[from] arrow::error::ArrowError),
37
38    /// Wraps errors from Parquet.
39    #[error("Parquet error: {0}")]
40    ParquetError(#[from] parquet::errors::ParquetError),
41
42    /// Indicates that an invalid parameter was provided (e.g., unsupported value or incorrect data type).
43    #[error("Invalid parameter: {0}")]
44    InvalidParameter(String),
45
46    /// Indicates that the provided data format is unsupported (e.g., unknown file format).
47    #[error("Unsupported format: {0}")]
48    UnsupportedFormat(String),
49
50    /// Indicates a feature or functionality has not yet been implemented.
51    #[error("Not implemented: {0}")]
52    NotImplemented(String),
53
54    /// Indicates that the specified column does not exist in the DataFrame.
55    #[error("Missing column: {0}")]
56    MissingColumn(String),
57
58    /// Indicates the transform method was called before calling fit for a stateful transformer.
59    #[error("Transform called before fit for stateful transformer")]
60    FitNotCalled,
61}
62
63/// A convenient result type for Feature Factory operations.
64pub type FeatureFactoryResult<T> = std::result::Result<T, FeatureFactoryError>;
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use std::io;
70
71    #[test]
72    fn test_io_error() {
73        // Create a simple I/O error.
74        let io_err = io::Error::new(io::ErrorKind::Other, "test io error");
75        let err: FeatureFactoryError = io_err.into();
76        let err_msg = format!("{}", err);
77        assert!(err_msg.contains("I/O error:"));
78        assert!(err_msg.contains("test io error"));
79    }
80
81    #[test]
82    fn test_datafusion_error() {
83        // Create a DataFusion error.
84        let df_err = datafusion::error::DataFusionError::Plan("test plan error".into());
85        let err: FeatureFactoryError = df_err.into();
86        let err_msg = format!("{}", err);
87        assert!(err_msg.contains("DataFusion error:"));
88        assert!(err_msg.contains("test plan error"));
89    }
90
91    #[test]
92    fn test_arrow_error() {
93        // Create an Arrow error.
94        let arrow_err = arrow::error::ArrowError::ComputeError("test compute error".into());
95        let err: FeatureFactoryError = arrow_err.into();
96        let err_msg = format!("{}", err);
97        assert!(err_msg.contains("Arrow error:"));
98        assert!(err_msg.contains("test compute error"));
99    }
100
101    #[test]
102    fn test_parquet_error() {
103        // Create a Parquet error.
104        let parquet_err = parquet::errors::ParquetError::General("test parquet error".into());
105        let err: FeatureFactoryError = parquet_err.into();
106        let err_msg = format!("{}", err);
107        assert!(err_msg.contains("Parquet error:"));
108        assert!(err_msg.contains("test parquet error"));
109    }
110
111    #[test]
112    fn test_invalid_parameter_error() {
113        let err = FeatureFactoryError::InvalidParameter("bad param".into());
114        let err_msg = format!("{}", err);
115        assert!(err_msg.contains("Invalid parameter:"));
116        assert!(err_msg.contains("bad param"));
117    }
118
119    #[test]
120    fn test_unsupported_format_error() {
121        let err = FeatureFactoryError::UnsupportedFormat("unknown format".into());
122        let err_msg = format!("{}", err);
123        assert!(err_msg.contains("Unsupported format:"));
124        assert!(err_msg.contains("unknown format"));
125    }
126
127    #[test]
128    fn test_not_implemented_error() {
129        let err = FeatureFactoryError::NotImplemented("feature not implemented".into());
130        let err_msg = format!("{}", err);
131        assert!(err_msg.contains("Not implemented:"));
132        assert!(err_msg.contains("feature not implemented"));
133    }
134
135    #[test]
136    fn test_missing_column_error() {
137        let err = FeatureFactoryError::MissingColumn("missing column".into());
138        let err_msg = format!("{}", err);
139        assert!(err_msg.contains("Missing column:"));
140        assert!(err_msg.contains("missing column"));
141    }
142
143    #[test]
144    fn test_fit_not_called_error() {
145        let err = FeatureFactoryError::FitNotCalled;
146        let err_msg = format!("{}", err);
147        assert!(err_msg.contains("Transform called before fit for stateful transformer"));
148    }
149}