Skip to main content

quantrs2_core/
error.rs

1use thiserror::Error;
2
3/// Common error types for quantum operations.
4///
5/// All fallible QuantRS2 operations return `Result<T, QuantRS2Error>` (aliased
6/// as [`QuantRS2Result<T>`]). Use `?` to propagate errors through call stacks.
7///
8/// # Examples
9///
10/// ```rust
11/// use quantrs2_core::error::{QuantRS2Error, QuantRS2Result};
12///
13/// fn validate_qubit(id: u32, num_qubits: u32) -> QuantRS2Result<()> {
14///     if id >= num_qubits {
15///         return Err(QuantRS2Error::InvalidQubitId(id));
16///     }
17///     Ok(())
18/// }
19///
20/// assert!(validate_qubit(0, 2).is_ok());
21/// assert!(validate_qubit(5, 2).is_err());
22/// ```
23#[derive(Error, Debug, Clone, PartialEq, Eq)]
24#[non_exhaustive]
25pub enum QuantRS2Error {
26    /// Error when a qubit is not in a valid range
27    #[error("Invalid qubit ID {0}, must be within the valid range for this operation")]
28    InvalidQubitId(u32),
29
30    /// Error when an operation is not supported
31    #[error("Unsupported operation: {0}")]
32    UnsupportedOperation(String),
33
34    /// Error when a gate application fails
35    #[error("Failed to apply gate: {0}")]
36    GateApplicationFailed(String),
37
38    /// Error when circuit validation fails
39    #[error("Circuit validation failed: {0}")]
40    CircuitValidationFailed(String),
41
42    /// Error when backend execution fails
43    #[error("Backend execution failed: {0}")]
44    BackendExecutionFailed(String),
45
46    /// Error when unsupported qubit count is requested
47    #[error("Unsupported qubit count {0}: {1}")]
48    UnsupportedQubits(usize, String),
49
50    /// Error when invalid input is provided
51    #[error("Invalid input: {0}")]
52    InvalidInput(String),
53
54    /// Error during computation
55    #[error("Computation error: {0}")]
56    ComputationError(String),
57
58    /// Linear algebra error
59    #[error("Linear algebra error: {0}")]
60    LinalgError(String),
61
62    /// Routing error
63    #[error("Routing error: {0}")]
64    RoutingError(String),
65
66    /// Matrix construction error
67    #[error("Matrix construction error: {0}")]
68    MatrixConstruction(String),
69
70    /// Matrix inversion error
71    #[error("Matrix inversion error: {0}")]
72    MatrixInversion(String),
73
74    /// Optimization failed error
75    #[error("Optimization failed: {0}")]
76    OptimizationFailed(String),
77
78    /// Tensor network error
79    #[error("Tensor network error: {0}")]
80    TensorNetwork(String),
81
82    /// Runtime error
83    #[error("Runtime error: {0}")]
84    RuntimeError(String),
85
86    /// Execution error
87    #[error("Execution error: {0}")]
88    ExecutionError(String),
89
90    /// Invalid gate operation
91    #[error("Invalid gate operation: {0}")]
92    InvalidGateOp(String),
93
94    /// UltraThink mode error variants
95    #[error("Invalid parameter: {0}")]
96    InvalidParameter(String),
97
98    #[error("Quantum decoherence: {0}")]
99    QuantumDecoherence(String),
100
101    #[error("No storage available: {0}")]
102    NoStorageAvailable(String),
103
104    #[error("Calibration not found: {0}")]
105    CalibrationNotFound(String),
106
107    #[error("Access denied: {0}")]
108    AccessDenied(String),
109
110    #[error("Storage capacity exceeded: {0}")]
111    StorageCapacityExceeded(String),
112
113    #[error("Hardware target not found: {0}")]
114    HardwareTargetNotFound(String),
115
116    #[error("Gate fusion error: {0}")]
117    GateFusionError(String),
118
119    #[error("Unsupported gate: {0}")]
120    UnsupportedGate(String),
121
122    #[error("Compilation timeout: {0}")]
123    CompilationTimeout(String),
124
125    #[error("Node not found: {0}")]
126    NodeNotFound(String),
127
128    #[error("Node unavailable: {0}")]
129    NodeUnavailable(String),
130
131    #[error("Network error: {0}")]
132    NetworkError(String),
133
134    #[error("No hardware available: {0}")]
135    NoHardwareAvailable(String),
136
137    #[error("State not found: {0}")]
138    StateNotFound(String),
139
140    #[error("Invalid operation: {0}")]
141    InvalidOperation(String),
142
143    #[error("QKD failure: {0}")]
144    QKDFailure(String),
145
146    #[error("Division by zero")]
147    DivisionByZero,
148
149    #[error("Lock poisoned: {0}")]
150    LockPoisoned(String),
151
152    #[error("Index {index} out of bounds for length {len}")]
153    IndexOutOfBounds { index: usize, len: usize },
154}
155
156/// Result type for quantum operations
157pub type QuantRS2Result<T> = Result<T, QuantRS2Error>;
158
159impl From<scirs2_core::ndarray::ShapeError> for QuantRS2Error {
160    fn from(err: scirs2_core::ndarray::ShapeError) -> Self {
161        Self::InvalidInput(format!("Shape error: {err}"))
162    }
163}
164
165#[cfg(feature = "mps")]
166impl From<scirs2_linalg::error::LinalgError> for QuantRS2Error {
167    fn from(err: scirs2_linalg::error::LinalgError) -> Self {
168        Self::LinalgError(format!("Linear algebra error: {err}"))
169    }
170}
171
172impl From<std::io::Error> for QuantRS2Error {
173    fn from(err: std::io::Error) -> Self {
174        Self::RuntimeError(format!("I/O error: {err}"))
175    }
176}
177
178impl From<oxicode::Error> for QuantRS2Error {
179    fn from(err: oxicode::Error) -> Self {
180        Self::RuntimeError(format!("Serialization error: {err:?}"))
181    }
182}
183
184impl From<serde_json::Error> for QuantRS2Error {
185    fn from(err: serde_json::Error) -> Self {
186        Self::RuntimeError(format!("JSON error: {err}"))
187    }
188}
189
190impl From<scirs2_core::linalg::LapackError> for QuantRS2Error {
191    fn from(err: scirs2_core::linalg::LapackError) -> Self {
192        Self::LinalgError(format!("LAPACK error: {err}"))
193    }
194}