Skip to main content

kunquant_rs/
error.rs

1use thiserror::Error;
2
3/// Comprehensive error types for KunQuant operations.
4///
5/// This enum covers all possible error conditions that can occur when using
6/// the KunQuant-rs library, from initialization failures to runtime computation
7/// errors. Each variant provides detailed context to help with debugging.
8///
9/// # Error Categories
10///
11/// - **Initialization Errors**: Executor, library, and buffer map creation failures
12/// - **Resource Errors**: Library loading, module lookup, and buffer handle errors
13/// - **Validation Errors**: Invalid parameters, buffer size mismatches, data constraints
14/// - **Runtime Errors**: Null pointers, computation failures, and system errors
15///
16/// # Error Handling
17///
18/// All KunQuant operations return `Result<T, KunQuantError>`, allowing for
19/// comprehensive error handling using Rust's `?` operator and pattern matching.
20///
21/// # Examples
22///
23/// ```rust,no_run
24/// use kunquant_rs::{Executor, KunQuantError};
25///
26/// match Executor::single_thread() {
27///     Ok(executor) => println!("Executor created successfully"),
28///     Err(KunQuantError::ExecutorCreationFailed) => {
29///         eprintln!("Failed to create executor - check KunQuant installation");
30///     }
31///     Err(e) => eprintln!("Unexpected error: {}", e),
32/// }
33/// ```
34#[derive(Error, Debug)]
35pub enum KunQuantError {
36    /// Failed to create a KunQuant executor.
37    ///
38    /// This error occurs when the underlying C library cannot create an executor,
39    /// typically due to insufficient system resources or library initialization issues.
40    ///
41    /// **Common Causes:**
42    /// - KunQuant C library not properly installed
43    /// - Insufficient memory for executor creation
44    /// - Invalid thread configuration (for multi-threaded executors)
45    /// - Missing required system dependencies
46    #[error("Failed to create executor")]
47    ExecutorCreationFailed,
48
49    /// Failed to load a KunQuant factor library from the specified path.
50    ///
51    /// This error indicates that the library file could not be loaded, either
52    /// because it doesn't exist, isn't accessible, or isn't a valid KunQuant library.
53    ///
54    /// **Common Causes:**
55    /// - File doesn't exist at the specified path
56    /// - Insufficient permissions to read the file
57    /// - Library compiled for incompatible architecture
58    /// - Missing shared library dependencies
59    /// - Corrupted or invalid library file
60    #[error("Failed to load library: {path}")]
61    LibraryLoadFailed { path: String },
62
63    /// The requested module was not found in the loaded library.
64    ///
65    /// This error occurs when trying to access a module that doesn't exist
66    /// in the loaded library, typically due to incorrect module names or
67    /// library compilation issues.
68    ///
69    /// **Common Causes:**
70    /// - Typo in module name (names are case-sensitive)
71    /// - Module not included during library compilation
72    /// - Library compiled with different module names
73    /// - Using wrong library file
74    #[error("Module not found: {name}")]
75    ModuleNotFound { name: String },
76
77    /// Failed to create a buffer name map for data management.
78    ///
79    /// This error indicates that the internal buffer management system
80    /// could not be initialized, typically due to memory allocation failures.
81    ///
82    /// **Common Causes:**
83    /// - Insufficient system memory
84    /// - Memory fragmentation
85    /// - System resource limits exceeded
86    #[error("Failed to create buffer name map")]
87    BufferNameMapCreationFailed,
88
89    /// The specified buffer name is invalid or contains illegal characters.
90    ///
91    /// Buffer names must be valid C strings without null bytes and should
92    /// match the names defined in the factor module.
93    ///
94    /// **Common Causes:**
95    /// - Buffer name contains null bytes ('\0')
96    /// - Empty buffer name
97    /// - Non-UTF8 characters in buffer name
98    #[error("Invalid buffer name: {name}")]
99    InvalidBufferName { name: String },
100
101    /// The number of stocks is not a multiple of 8, which is required for SIMD optimization.
102    ///
103    /// KunQuant uses SIMD (Single Instruction, Multiple Data) instructions for
104    /// performance optimization, which requires the stock count to be divisible by 8.
105    ///
106    /// **Solution:** Use a stock count that is a multiple of 8 (e.g., 8, 16, 24, 32, ...).
107    #[error("Invalid number of stocks: {num_stocks}. Must be a multiple of 8")]
108    InvalidStockCount { num_stocks: usize },
109
110    /// Buffer size doesn't match the expected dimensions for the computation.
111    ///
112    /// This error occurs when the provided buffer size doesn't match the
113    /// expected size based on the number of stocks and time points.
114    ///
115    /// **Expected Size:** `num_stocks * total_time` for time-series data
116    #[error("Buffer size mismatch for '{name}': expected {expected}, got {actual}")]
117    BufferSizeMismatch {
118        name: String,
119        expected: usize,
120        actual: usize,
121    },
122
123    /// Failed to create a streaming computation context.
124    ///
125    /// This error occurs when the streaming context cannot be initialized,
126    /// typically due to incompatible module settings or resource constraints.
127    ///
128    /// **Common Causes:**
129    /// - Module not compiled with `output_layout="STREAM"`
130    /// - Invalid number of stocks (not multiple of 8)
131    /// - Insufficient memory for streaming buffers
132    /// - Incompatible module and executor combination
133    #[error("Stream context creation failed")]
134    StreamCreationFailed,
135
136    /// The requested buffer handle was not found in the streaming context.
137    ///
138    /// This error occurs when trying to access a buffer that hasn't been
139    /// registered or doesn't exist in the current streaming context.
140    ///
141    /// **Common Causes:**
142    /// - Buffer name doesn't match module definition
143    /// - Buffer not properly initialized in streaming context
144    /// - Typo in buffer name (names are case-sensitive)
145    #[error("Buffer handle not found: {name}")]
146    BufferHandleNotFound { name: String },
147
148    /// A null pointer was encountered during C library interaction.
149    ///
150    /// This error indicates a serious internal issue where a C library
151    /// function returned a null pointer unexpectedly.
152    ///
153    /// **Common Causes:**
154    /// - Memory allocation failure in C library
155    /// - Invalid handle passed to C function
156    /// - Library corruption or version mismatch
157    /// - System resource exhaustion
158    #[error("Null pointer encountered")]
159    NullPointer,
160
161    /// Error converting Rust string to C string (contains null bytes).
162    ///
163    /// This error occurs when a Rust string contains null bytes ('\0'),
164    /// which are not allowed in C strings used by the KunQuant library.
165    ///
166    /// **Solution:** Ensure strings don't contain null bytes.
167    #[error("String conversion error: {0}")]
168    StringConversion(#[from] std::ffi::NulError),
169
170    /// Error converting C string to UTF-8.
171    ///
172    /// This error occurs when the C library returns a string that
173    /// contains invalid UTF-8 sequences.
174    ///
175    /// **Common Causes:**
176    /// - Corrupted data from C library
177    /// - Encoding mismatch between C and Rust
178    /// - Memory corruption
179    #[error("UTF-8 conversion error: {0}")]
180    Utf8Conversion(#[from] std::str::Utf8Error),
181}
182
183/// Type alias for Results using KunQuantError.
184///
185/// This is a convenience type alias that simplifies function signatures
186/// throughout the KunQuant-rs library. Instead of writing
187/// `std::result::Result<T, KunQuantError>`, you can simply use `Result<T>`.
188///
189/// # Examples
190///
191/// ```rust,no_run
192/// use kunquant_rs::Result;
193///
194/// fn create_executor() -> Result<()> {
195///     // Function implementation
196///     Ok(())
197/// }
198/// ```
199pub type Result<T> = std::result::Result<T, KunQuantError>;