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!(
78                    f,
79                    "Matrix is singular (perfect multicollinearity). Remove redundant variables."
80                )
81            },
82            Error::InsufficientData {
83                required,
84                available,
85            } => {
86                write!(
87                    f,
88                    "Insufficient data: need at least {} observations, have {}",
89                    required, available
90                )
91            },
92            Error::InvalidInput(msg) => {
93                write!(f, "Invalid input: {}", msg)
94            },
95            Error::DimensionMismatch(msg) => {
96                write!(f, "Dimension mismatch: {}", msg)
97            },
98            Error::ComputationFailed(msg) => {
99                write!(f, "Computation failed: {}", msg)
100            },
101            Error::ParseError(msg) => {
102                write!(f, "Parse error: {}", msg)
103            },
104            Error::DomainCheck(msg) => {
105                write!(f, "Domain check failed: {}", msg)
106            },
107        }
108    }
109}
110
111impl std::error::Error for Error {}
112
113/// Result type for linear regression operations.
114///
115/// Alias for `std::result::Result<T, Error>`.
116///
117/// # Example
118///
119/// ```
120/// # use linreg_core::{Error, Result};
121/// # fn falls_back() -> Result<f64> {
122/// #     Ok(42.0)
123/// # }
124/// let result: Result<f64> = falls_back();
125/// assert_eq!(result.unwrap(), 42.0);
126/// ```
127pub type Result<T> = std::result::Result<T, Error>;
128
129// ============================================================================
130// Helper Functions for WASM Integration
131// ============================================================================
132//
133// These functions convert errors to JSON format for use in WASM bindings,
134// enabling proper error reporting to JavaScript code.
135
136/// Converts an error message to a JSON error string.
137///
138/// Creates a JSON object with a single "error" field containing the message.
139/// Used in WASM bindings to return error information to JavaScript.
140///
141/// # Examples
142///
143/// ```
144/// # use linreg_core::error_json;
145/// let json = error_json("Invalid input");
146/// assert_eq!(json, r#"{"error":"Invalid input"}"#);
147/// ```
148pub fn error_json(msg: &str) -> String {
149    serde_json::json!({ "error": msg }).to_string()
150}
151
152/// Converts an [`Error`] to a JSON error string.
153///
154/// Convenience function that converts any error variant to its display
155/// representation and wraps it in a JSON object.
156///
157/// # Examples
158///
159/// ```
160/// # use linreg_core::Error;
161/// # use linreg_core::error_to_json;
162/// let err = Error::SingularMatrix;
163/// let json = error_to_json(&err);
164/// assert!(json.contains("singular"));
165/// ```
166pub fn error_to_json(err: &Error) -> String {
167    error_json(&err.to_string())
168}