Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
348
vendor/ruvector/crates/ruQu/src/error.rs
vendored
Normal file
348
vendor/ruvector/crates/ruQu/src/error.rs
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
//! Error types for the ruQu coherence gate system
|
||||
//!
|
||||
//! This module defines all error types that can occur during coherence
|
||||
//! assessment, syndrome processing, and gate decision-making.
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Result type alias for ruQu operations
|
||||
pub type Result<T> = std::result::Result<T, RuQuError>;
|
||||
|
||||
/// Main error type for ruQu operations
|
||||
#[derive(Error, Debug)]
|
||||
pub enum RuQuError {
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Gate Decision Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Filter evaluation failed
|
||||
#[error("Filter evaluation failed: {filter} - {reason}")]
|
||||
FilterEvaluationFailed {
|
||||
/// Which filter failed
|
||||
filter: String,
|
||||
/// Reason for failure
|
||||
reason: String,
|
||||
},
|
||||
|
||||
/// Gate decision timeout exceeded
|
||||
#[error("Gate decision timeout: {elapsed_ns}ns exceeded {budget_ns}ns budget")]
|
||||
DecisionTimeout {
|
||||
/// Time elapsed in nanoseconds
|
||||
elapsed_ns: u64,
|
||||
/// Budget in nanoseconds
|
||||
budget_ns: u64,
|
||||
},
|
||||
|
||||
/// Invalid threshold configuration
|
||||
#[error("Invalid threshold: {name} = {value} (expected {constraint})")]
|
||||
InvalidThreshold {
|
||||
/// Threshold name
|
||||
name: String,
|
||||
/// Actual value
|
||||
value: f64,
|
||||
/// Expected constraint description
|
||||
constraint: String,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Tile Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Invalid tile identifier
|
||||
#[error("Invalid tile ID: {0} (valid range: 0-255)")]
|
||||
InvalidTileId(u16),
|
||||
|
||||
/// Tile not found
|
||||
#[error("Tile {0} not found in fabric")]
|
||||
TileNotFound(u8),
|
||||
|
||||
/// Tile communication failure
|
||||
#[error("Tile communication failed: tile {tile_id} - {reason}")]
|
||||
TileCommunicationFailed {
|
||||
/// Tile that failed
|
||||
tile_id: u8,
|
||||
/// Reason for failure
|
||||
reason: String,
|
||||
},
|
||||
|
||||
/// Tile memory exceeded
|
||||
#[error("Tile {tile_id} memory exceeded: {used} bytes > {limit} bytes")]
|
||||
TileMemoryExceeded {
|
||||
/// Tile ID
|
||||
tile_id: u8,
|
||||
/// Memory used
|
||||
used: usize,
|
||||
/// Memory limit
|
||||
limit: usize,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Syndrome Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Syndrome buffer overflow
|
||||
#[error("Syndrome buffer overflow: capacity {capacity}, attempted write at {position}")]
|
||||
SyndromeBufferOverflow {
|
||||
/// Buffer capacity
|
||||
capacity: usize,
|
||||
/// Attempted write position
|
||||
position: usize,
|
||||
},
|
||||
|
||||
/// Invalid syndrome round
|
||||
#[error("Invalid syndrome round: {0}")]
|
||||
InvalidSyndromeRound(String),
|
||||
|
||||
/// Syndrome gap detected (missing rounds)
|
||||
#[error("Syndrome gap: expected round {expected}, got {actual}")]
|
||||
SyndromeGap {
|
||||
/// Expected round ID
|
||||
expected: u64,
|
||||
/// Actual round ID received
|
||||
actual: u64,
|
||||
},
|
||||
|
||||
/// Detector map mismatch
|
||||
#[error("Detector count mismatch: expected {expected}, got {actual}")]
|
||||
DetectorCountMismatch {
|
||||
/// Expected detector count
|
||||
expected: usize,
|
||||
/// Actual detector count
|
||||
actual: usize,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Graph Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Graph vertex not found
|
||||
#[error("Vertex {0} not found in operational graph")]
|
||||
VertexNotFound(u64),
|
||||
|
||||
/// Graph edge not found
|
||||
#[error("Edge {0} not found in operational graph")]
|
||||
EdgeNotFound(u64),
|
||||
|
||||
/// Invalid graph update
|
||||
#[error("Invalid graph update: {0}")]
|
||||
InvalidGraphUpdate(String),
|
||||
|
||||
/// Graph version conflict
|
||||
#[error("Graph version conflict: expected {expected}, current {current}")]
|
||||
GraphVersionConflict {
|
||||
/// Expected version
|
||||
expected: u64,
|
||||
/// Current version
|
||||
current: u64,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Permit/Token Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Permit token expired
|
||||
#[error("Permit token expired: expired at {expired_at}, current time {current_time}")]
|
||||
PermitExpired {
|
||||
/// Expiration timestamp
|
||||
expired_at: u64,
|
||||
/// Current timestamp
|
||||
current_time: u64,
|
||||
},
|
||||
|
||||
/// Permit signature invalid
|
||||
#[error("Permit signature verification failed")]
|
||||
PermitSignatureInvalid,
|
||||
|
||||
/// Permit witness hash mismatch
|
||||
#[error("Permit witness hash mismatch")]
|
||||
PermitWitnessMismatch,
|
||||
|
||||
/// Action not authorized by permit
|
||||
#[error("Action {action_id} not authorized by permit for regions {region_mask:?}")]
|
||||
ActionNotAuthorized {
|
||||
/// Action ID
|
||||
action_id: String,
|
||||
/// Region mask from permit
|
||||
region_mask: [u64; 4],
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Witness/Receipt Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Witness chain broken
|
||||
#[error("Witness chain broken at sequence {sequence}")]
|
||||
WitnessChainBroken {
|
||||
/// Sequence where chain broke
|
||||
sequence: u64,
|
||||
},
|
||||
|
||||
/// Receipt not found
|
||||
#[error("Receipt not found for sequence {0}")]
|
||||
ReceiptNotFound(u64),
|
||||
|
||||
/// Receipt verification failed
|
||||
#[error("Receipt verification failed at sequence {sequence}: {reason}")]
|
||||
ReceiptVerificationFailed {
|
||||
/// Sequence number
|
||||
sequence: u64,
|
||||
/// Failure reason
|
||||
reason: String,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Fabric Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Fabric not initialized
|
||||
#[error("Quantum fabric not initialized")]
|
||||
FabricNotInitialized,
|
||||
|
||||
/// Fabric configuration invalid
|
||||
#[error("Invalid fabric configuration: {0}")]
|
||||
InvalidFabricConfig(String),
|
||||
|
||||
/// Fabric synchronization failed
|
||||
#[error("Fabric synchronization failed: {0}")]
|
||||
FabricSyncFailed(String),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// Integration Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// MinCut integration error
|
||||
#[error("MinCut error: {0}")]
|
||||
MinCutError(String),
|
||||
|
||||
/// TileZero integration error
|
||||
#[error("TileZero error: {0}")]
|
||||
TileZeroError(String),
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
// General Errors
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
/// Internal error
|
||||
#[error("Internal error: {0}")]
|
||||
Internal(String),
|
||||
|
||||
/// Serialization error
|
||||
#[error("Serialization error: {0}")]
|
||||
Serialization(String),
|
||||
|
||||
/// IO error
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl RuQuError {
|
||||
/// Check if error is recoverable (can retry operation)
|
||||
pub fn is_recoverable(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
RuQuError::DecisionTimeout { .. }
|
||||
| RuQuError::TileCommunicationFailed { .. }
|
||||
| RuQuError::SyndromeGap { .. }
|
||||
| RuQuError::FabricSyncFailed(_)
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if error indicates data corruption
|
||||
pub fn is_corruption(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
RuQuError::WitnessChainBroken { .. }
|
||||
| RuQuError::ReceiptVerificationFailed { .. }
|
||||
| RuQuError::PermitSignatureInvalid
|
||||
| RuQuError::PermitWitnessMismatch
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if error is a configuration problem
|
||||
pub fn is_configuration(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
RuQuError::InvalidThreshold { .. }
|
||||
| RuQuError::InvalidFabricConfig(_)
|
||||
| RuQuError::DetectorCountMismatch { .. }
|
||||
)
|
||||
}
|
||||
|
||||
/// Check if error is resource-related
|
||||
pub fn is_resource(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
RuQuError::TileMemoryExceeded { .. } | RuQuError::SyndromeBufferOverflow { .. }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for RuQuError {
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
RuQuError::Serialization(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for RuQuError {
|
||||
fn from(msg: String) -> Self {
|
||||
RuQuError::Internal(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for RuQuError {
|
||||
fn from(msg: &str) -> Self {
|
||||
RuQuError::Internal(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_error_display() {
|
||||
let err = RuQuError::InvalidTileId(300);
|
||||
assert_eq!(err.to_string(), "Invalid tile ID: 300 (valid range: 0-255)");
|
||||
|
||||
let err = RuQuError::DecisionTimeout {
|
||||
elapsed_ns: 5000,
|
||||
budget_ns: 4000,
|
||||
};
|
||||
assert!(err.to_string().contains("5000ns"));
|
||||
assert!(err.to_string().contains("4000ns"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_recoverable() {
|
||||
assert!(RuQuError::DecisionTimeout {
|
||||
elapsed_ns: 5000,
|
||||
budget_ns: 4000
|
||||
}
|
||||
.is_recoverable());
|
||||
|
||||
assert!(RuQuError::TileCommunicationFailed {
|
||||
tile_id: 1,
|
||||
reason: "timeout".to_string()
|
||||
}
|
||||
.is_recoverable());
|
||||
|
||||
assert!(!RuQuError::PermitSignatureInvalid.is_recoverable());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_corruption() {
|
||||
assert!(RuQuError::WitnessChainBroken { sequence: 42 }.is_corruption());
|
||||
assert!(RuQuError::PermitSignatureInvalid.is_corruption());
|
||||
assert!(!RuQuError::InvalidTileId(300).is_corruption());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_configuration() {
|
||||
assert!(RuQuError::InvalidThreshold {
|
||||
name: "tau_deny".to_string(),
|
||||
value: -1.0,
|
||||
constraint: "> 0".to_string()
|
||||
}
|
||||
.is_configuration());
|
||||
|
||||
assert!(!RuQuError::Internal("oops".to_string()).is_configuration());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_string() {
|
||||
let err: RuQuError = "test error".into();
|
||||
assert!(matches!(err, RuQuError::Internal(_)));
|
||||
assert_eq!(err.to_string(), "Internal error: test error");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user