201 lines
5.4 KiB
Rust
201 lines
5.4 KiB
Rust
//! Error types for PINN benchmark operations
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Errors that can occur during PINN operations
|
|
#[derive(Debug, Error)]
|
|
pub enum PINNError {
|
|
/// Network architecture error
|
|
#[error("Network error: {0}")]
|
|
Network(String),
|
|
|
|
/// Training error
|
|
#[error("Training error: {0}")]
|
|
Training(String),
|
|
|
|
/// Benchmark error
|
|
#[error("Benchmark error: {0}")]
|
|
Benchmark(String),
|
|
|
|
/// Invalid configuration
|
|
#[error("Invalid configuration: {0}")]
|
|
InvalidConfig(String),
|
|
|
|
/// Numerical computation error
|
|
#[error("Numerical error: {0}")]
|
|
Numerical(String),
|
|
|
|
/// I/O error
|
|
#[error("I/O error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
|
|
/// Serialization error
|
|
#[error("Serialization error: {0}")]
|
|
Serialization(#[from] serde_json::Error),
|
|
}
|
|
|
|
/// Result type for PINN operations
|
|
pub type Result<T> = std::result::Result<T, PINNError>;
|
|
|
|
impl PINNError {
|
|
/// Creates a network error
|
|
pub fn network<S: Into<String>>(msg: S) -> Self {
|
|
Self::Network(msg.into())
|
|
}
|
|
|
|
/// Creates a training error
|
|
pub fn training<S: Into<String>>(msg: S) -> Self {
|
|
Self::Training(msg.into())
|
|
}
|
|
|
|
/// Creates a benchmark error
|
|
pub fn benchmark<S: Into<String>>(msg: S) -> Self {
|
|
Self::Benchmark(msg.into())
|
|
}
|
|
|
|
/// Creates an invalid configuration error
|
|
pub fn invalid_config<S: Into<String>>(msg: S) -> Self {
|
|
Self::InvalidConfig(msg.into())
|
|
}
|
|
|
|
/// Creates a numerical error
|
|
pub fn numerical<S: Into<String>>(msg: S) -> Self {
|
|
Self::Numerical(msg.into())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_network_error_creation() {
|
|
let err = PINNError::network("invalid layer size");
|
|
assert!(matches!(err, PINNError::Network(_)));
|
|
assert_eq!(err.to_string(), "Network error: invalid layer size");
|
|
}
|
|
|
|
#[test]
|
|
fn test_training_error_creation() {
|
|
let err = PINNError::training("loss diverged");
|
|
assert!(matches!(err, PINNError::Training(_)));
|
|
assert_eq!(err.to_string(), "Training error: loss diverged");
|
|
}
|
|
|
|
#[test]
|
|
fn test_benchmark_error_creation() {
|
|
let err = PINNError::benchmark("invalid problem type");
|
|
assert!(matches!(err, PINNError::Benchmark(_)));
|
|
assert_eq!(err.to_string(), "Benchmark error: invalid problem type");
|
|
}
|
|
|
|
#[test]
|
|
fn test_invalid_config_error_creation() {
|
|
let err = PINNError::invalid_config("learning rate must be positive");
|
|
assert!(matches!(err, PINNError::InvalidConfig(_)));
|
|
assert!(err.to_string().contains("learning rate"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_numerical_error_creation() {
|
|
let err = PINNError::numerical("NaN detected");
|
|
assert!(matches!(err, PINNError::Numerical(_)));
|
|
assert_eq!(err.to_string(), "Numerical error: NaN detected");
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_is_send_and_sync() {
|
|
fn assert_send_sync<T: Send + Sync>() {}
|
|
assert_send_sync::<PINNError>();
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_display_network() {
|
|
let err = PINNError::Network("test message".to_string());
|
|
let display = format!("{err}");
|
|
assert_eq!(display, "Network error: test message");
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_display_training() {
|
|
let err = PINNError::Training("gradient overflow".to_string());
|
|
let display = format!("{err}");
|
|
assert_eq!(display, "Training error: gradient overflow");
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_from_string_slice() {
|
|
let err = PINNError::network("test");
|
|
assert!(matches!(err, PINNError::Network(_)));
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_from_string() {
|
|
let msg = String::from("owned string");
|
|
let err = PINNError::training(msg);
|
|
assert!(matches!(err, PINNError::Training(_)));
|
|
}
|
|
|
|
#[test]
|
|
fn test_result_type_ok() {
|
|
let result: Result<i32> = Ok(42);
|
|
assert!(result.is_ok());
|
|
assert_eq!(result.unwrap(), 42);
|
|
}
|
|
|
|
#[test]
|
|
fn test_result_type_err() {
|
|
let result: Result<i32> = Err(PINNError::network("failed"));
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_chain_with_question_mark() {
|
|
fn inner_fn() -> Result<i32> {
|
|
Err(PINNError::network("inner error"))
|
|
}
|
|
|
|
fn outer_fn() -> Result<i32> {
|
|
inner_fn()?;
|
|
Ok(42)
|
|
}
|
|
|
|
let result = outer_fn();
|
|
assert!(result.is_err());
|
|
assert!(matches!(result.unwrap_err(), PINNError::Network(_)));
|
|
}
|
|
|
|
#[test]
|
|
fn test_multiple_error_types() {
|
|
let errors = vec![
|
|
PINNError::network("net"),
|
|
PINNError::training("train"),
|
|
PINNError::benchmark("bench"),
|
|
PINNError::invalid_config("config"),
|
|
PINNError::numerical("num"),
|
|
];
|
|
|
|
assert_eq!(errors.len(), 5);
|
|
for err in errors {
|
|
assert!(!err.to_string().is_empty());
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_debug_format() {
|
|
let err = PINNError::network("debug test");
|
|
let debug = format!("{err:?}");
|
|
assert!(debug.contains("Network"));
|
|
assert!(debug.contains("debug test"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_serde_json_error_conversion() {
|
|
let json_err = serde_json::from_str::<serde_json::Value>("invalid json");
|
|
assert!(json_err.is_err());
|
|
|
|
let pinn_err = PINNError::from(json_err.unwrap_err());
|
|
assert!(matches!(pinn_err, PINNError::Serialization(_)));
|
|
}
|
|
}
|