linreg_core/
error.rs

1//! Error types for the linear regression library.
2//!
3//! This module provides a comprehensive error type for all failure modes in
4//! linear regression operations, including matrix operations, statistical
5//! computations, and data parsing.
6
7use std::fmt;
8
9/// Error types for linear regression operations
10#[derive(Debug, Clone, PartialEq)]
11pub enum Error {
12    /// Matrix is singular (perfect multicollinearity).
13    ///
14    /// This occurs when one or more predictor variables are linear combinations
15    /// of others, making the matrix non-invertible. Remove redundant variables
16    /// to resolve this error.
17    SingularMatrix,
18
19    /// Insufficient data points for the model.
20    ///
21    /// OLS regression requires more observations than predictor variables.
22    InsufficientData {
23        /// Minimum number of observations required
24        required: usize,
25        /// Actual number of observations available
26        available: usize,
27    },
28
29    /// Invalid input parameter.
30    ///
31    /// Indicates that an input parameter has an invalid value (e.g., negative
32    /// variance, empty data arrays, incompatible dimensions).
33    InvalidInput(String),
34
35    /// Parse error for JSON/CSV data.
36    ///
37    /// Raised when input data cannot be parsed as JSON or CSV.
38    ParseError(String),
39
40    /// Domain check failed (for WASM with domain restriction enabled).
41    ///
42    /// By default, the WASM module allows all domains. This error is only returned
43    /// when the `LINREG_DOMAIN_RESTRICT` environment variable is set at build time
44    /// and the module is accessed from an unauthorized domain.
45    ///
46    /// To enable domain restriction:
47    /// ```bash
48    /// LINREG_DOMAIN_RESTRICT=example.com,yoursite.com wasm-pack build
49    /// ```
50    DomainCheck(String),
51}
52
53impl fmt::Display for Error {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Error::SingularMatrix => {
57                write!(f, "Matrix is singular (perfect multicollinearity). Remove redundant variables.")
58            }
59            Error::InsufficientData { required, available } => {
60                write!(f, "Insufficient data: need at least {} observations, have {}", required, available)
61            }
62            Error::InvalidInput(msg) => {
63                write!(f, "Invalid input: {}", msg)
64            }
65            Error::ParseError(msg) => {
66                write!(f, "Parse error: {}", msg)
67            }
68            Error::DomainCheck(msg) => {
69                write!(f, "Domain check failed: {}", msg)
70            }
71        }
72    }
73}
74
75impl std::error::Error for Error {}
76
77/// Result type for linear regression operations.
78///
79/// Alias for `std::result::Result<T, Error>`.
80pub type Result<T> = std::result::Result<T, Error>;
81
82// ============================================================================
83// Helper Functions for WASM Integration
84// ============================================================================
85//
86// These functions convert errors to JSON format for use in WASM bindings,
87// enabling proper error reporting to JavaScript code.
88
89/// Converts an error message to a JSON error string.
90///
91/// Creates a JSON object with a single "error" field containing the message.
92/// Used in WASM bindings to return error information to JavaScript.
93///
94/// # Examples
95///
96/// ```
97/// # use linreg_core::error_json;
98/// let json = error_json("Invalid input");
99/// assert_eq!(json, r#"{"error":"Invalid input"}"#);
100/// ```
101pub fn error_json(msg: &str) -> String {
102    serde_json::json!({ "error": msg }).to_string()
103}
104
105/// Converts an [`Error`] to a JSON error string.
106///
107/// Convenience function that converts any error variant to its display
108/// representation and wraps it in a JSON object.
109///
110/// # Examples
111///
112/// ```
113/// # use linreg_core::Error;
114/// # use linreg_core::error_to_json;
115/// let err = Error::SingularMatrix;
116/// let json = error_to_json(&err);
117/// assert!(json.contains("singular"));
118/// ```
119pub fn error_to_json(err: &Error) -> String {
120    error_json(&err.to_string())
121}