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///
11/// # Example
12///
13/// ```
14/// # use linreg_core::Error;
15/// let err = Error::InvalidInput("negative value".to_string());
16/// assert!(err.to_string().contains("Invalid input"));
17/// ```
18#[derive(Debug, Clone, PartialEq)]
19pub enum Error {
20    /// Matrix is singular (perfect multicollinearity).
21    ///
22    /// This occurs when one or more predictor variables are linear combinations
23    /// of others, making the matrix non-invertible. Remove redundant variables
24    /// to resolve this error.
25    SingularMatrix,
26
27    /// Insufficient data points for the model.
28    ///
29    /// OLS regression requires more observations than predictor variables.
30    InsufficientData {
31        /// Minimum number of observations required
32        required: usize,
33        /// Actual number of observations available
34        available: usize,
35    },
36
37    /// Invalid input parameter.
38    ///
39    /// Indicates that an input parameter has an invalid value (e.g., negative
40    /// variance, empty data arrays, incompatible dimensions).
41    InvalidInput(String),
42
43    /// Dimension mismatch in matrix/vector operations.
44    ///
45    /// This occurs when the dimensions of matrices or vectors are incompatible
46    /// for the requested operation.
47    DimensionMismatch(String),
48
49    /// Computation failed due to numerical issues.
50    ///
51    /// This occurs when a numerical computation fails due to issues like
52    /// singularity, non-convergence, or overflow/underflow.
53    ComputationFailed(String),
54
55    /// Parse error for JSON/CSV data.
56    ///
57    /// Raised when input data cannot be parsed as JSON or CSV.
58    ParseError(String),
59
60    /// Domain check failed (for WASM with domain restriction enabled).
61    ///
62    /// By default, the WASM module allows all domains. This error is only returned
63    /// when the `LINREG_DOMAIN_RESTRICT` environment variable is set at build time
64    /// and the module is accessed from an unauthorized domain.
65    ///
66    /// To enable domain restriction:
67    /// ```bash
68    /// LINREG_DOMAIN_RESTRICT=example.com,yoursite.com wasm-pack build
69    /// ```
70    DomainCheck(String),
71}
72
73impl fmt::Display for Error {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        match self {
76            Error::SingularMatrix => {
77                write!(f, "Matrix is singular (perfect multicollinearity). Remove redundant variables.")
78            }
79            Error::InsufficientData { required, available } => {
80                write!(f, "Insufficient data: need at least {} observations, have {}", required, available)
81            }
82            Error::InvalidInput(msg) => {
83                write!(f, "Invalid input: {}", msg)
84            }
85            Error::DimensionMismatch(msg) => {
86                write!(f, "Dimension mismatch: {}", msg)
87            }
88            Error::ComputationFailed(msg) => {
89                write!(f, "Computation failed: {}", msg)
90            }
91            Error::ParseError(msg) => {
92                write!(f, "Parse error: {}", msg)
93            }
94            Error::DomainCheck(msg) => {
95                write!(f, "Domain check failed: {}", msg)
96            }
97        }
98    }
99}
100
101impl std::error::Error for Error {}
102
103/// Result type for linear regression operations.
104///
105/// Alias for `std::result::Result<T, Error>`.
106///
107/// # Example
108///
109/// ```
110/// # use linreg_core::{Error, Result};
111/// # fn falls_back() -> Result<f64> {
112/// #     Ok(42.0)
113/// # }
114/// let result: Result<f64> = falls_back();
115/// assert_eq!(result.unwrap(), 42.0);
116/// ```
117pub type Result<T> = std::result::Result<T, Error>;
118
119// ============================================================================
120// Helper Functions for WASM Integration
121// ============================================================================
122//
123// These functions convert errors to JSON format for use in WASM bindings,
124// enabling proper error reporting to JavaScript code.
125
126/// Converts an error message to a JSON error string.
127///
128/// Creates a JSON object with a single "error" field containing the message.
129/// Used in WASM bindings to return error information to JavaScript.
130///
131/// # Examples
132///
133/// ```
134/// # use linreg_core::error_json;
135/// let json = error_json("Invalid input");
136/// assert_eq!(json, r#"{"error":"Invalid input"}"#);
137/// ```
138pub fn error_json(msg: &str) -> String {
139    serde_json::json!({ "error": msg }).to_string()
140}
141
142/// Converts an [`Error`] to a JSON error string.
143///
144/// Convenience function that converts any error variant to its display
145/// representation and wraps it in a JSON object.
146///
147/// # Examples
148///
149/// ```
150/// # use linreg_core::Error;
151/// # use linreg_core::error_to_json;
152/// let err = Error::SingularMatrix;
153/// let json = error_to_json(&err);
154/// assert!(json.contains("singular"));
155/// ```
156pub fn error_to_json(err: &Error) -> String {
157    error_json(&err.to_string())
158}