polars_view/
error.rs

1use polars::prelude::PolarsError;
2use std::{io, path::PathBuf};
3use thiserror::Error;
4use tokio::task::JoinError;
5
6/**
7Result type to simplify function signatures.
8
9This is a custom result type that uses our custom `PolarsViewError` for the error type.
10
11Functions can return `PolarsViewResult<T>` and then use `?` to automatically propagate errors.
12*/
13pub type PolarsViewResult<T> = Result<T, PolarsViewError>;
14
15/**
16Custom error type for Polars View.
17
18This enum defines all the possible errors that can occur in the application.
19
20We use the `thiserror` crate to derive the `Error` trait and automatically
21implement `Display` using the `#[error(...)]` attribute.
22*/
23#[derive(Error, Debug)]
24pub enum PolarsViewError {
25    // Errors occurring when receiving data from asynchronous channels.
26    #[error("Channel receive error: {0}")]
27    ChannelReceive(String),
28
29    // Errors encountered while parsing CSV data (e.g., inconsistent columns, invalid data).
30    #[error("CSV parsing error: {0}")]
31    CsvParsing(String),
32
33    // Indicates that a specified file could not be found, storing the attempted path.
34    #[error("File not found: {0:#?}")]
35    FileNotFound(PathBuf),
36
37    // Errors related to the file type (e.g., unsupported file extension, incorrect file format).
38    #[error("File type error: {0}")]
39    FileType(String),
40
41    // Wrapper for standard IO errors.
42    // The #[from] attribute automatically converts io::Error to PolarsViewError::Io.
43    #[error("IO error: {0}")]
44    Io(#[from] io::Error),
45
46    // --- End Regex Errors ---
47    #[error("Invalid value for command-line argument '{arg_name}': {reason}")]
48    InvalidArgument {
49        arg_name: String, // Context about *which* argument failed
50        reason: String,   // The specific error reason
51    },
52
53    /// Indicates that the regex pattern matched columns that are not `DataType::String`, which is required for normalization.
54    #[error(
55        "Regex pattern '{pattern}' matched non-string columns which cannot be normalized:\n\
56         {columns:#?}\n\
57         Please adjust the regex pattern to exclusively target String columns."
58    )]
59    InvalidDataTypeForRegex {
60        pattern: String,
61        /// List of problematic columns (name and type)
62        columns: Vec<String>,
63    },
64
65    // Indicates an invalid CSV delimiter was provided (empty or too long).
66    #[error("Invalid CSV delimiter: '{0}'")] // Added quotes for clarity
67    InvalidDelimiter(String),
68
69    // --- Regex Errors ---
70    /// Indicates that a regex pattern provided for column selection does not meet the required format (`*` or `^...$`).
71    #[error(
72        "Invalid regex pattern for column selection: '{0}'.\n\
73        Pattern must be '*' or (start with '^' and end with '$')."
74    )]
75    InvalidRegexPattern(String),
76
77    /// Indicates that the provided regex pattern has invalid syntax.
78    #[error("Invalid regex syntax in pattern '{pattern}'\n{error}")]
79    InvalidRegexSyntax { pattern: String, error: String },
80
81    // Wrapper for Polars errors (from the Polars library).
82    // #[from] handles conversion. Handles errors from Polars operations,
83    // including invalid lazy plans or errors during execution (like bad casts or regex syntax).
84    #[error("Polars error: {0}")]
85    Polars(#[from] PolarsError),
86
87    // Wrapper for Tokio JoinErrors, occurring when asynchronous tasks fail.
88    #[error("Tokio JoinError: {0}")]
89    TokioJoin(#[from] JoinError),
90
91    // Indicates that a provided file extension or file type are not supported.
92    #[error("Unsupported file type: {0}")]
93    UnsupportedFileType(String),
94
95    // A catch-all for other, less specific errors not covered by specific variants.
96    // Uses a String to describe the error. Consider using this sparingly.
97    #[error("Other error: {0}")]
98    Other(String),
99}
100
101// Implementation of the From trait to convert a String into a PolarsViewError.
102// This allows us to easily convert generic error strings into our custom error type.
103impl From<String> for PolarsViewError {
104    fn from(err: String) -> PolarsViewError {
105        // Prefer using specific error variants when possible, fallback to Other.
106        PolarsViewError::Other(err)
107    }
108}