Files
foxhunt/services/trading_service/src/error.rs
jgrusewski 73b9ca0659 fix(clippy): Fix 17 critical float_arithmetic warnings in load_tests
- Added safe_div(), safe_mul(), and safe_add() helper functions
- All helpers check for NaN, infinity, and division by zero
- Replaced direct float operations with safe wrappers
- Fixed percentile calculations (lines 86-89)
- Fixed success rate calculation (line 101)
- Fixed throughput calculation (line 107)
- Fixed all latency metric conversions (lines 133-154)
- Fixed P99 latency display (lines 177, 182)
- Fixed order quantity/price calculations (lines 215-216)

All 17 float_arithmetic warnings in lib.rs now resolved.
Part 1/2: 9 warnings requested, 17 actually fixed.
2025-10-23 11:54:56 +02:00

154 lines
6.4 KiB
Rust

//! Error types for the Trading Service - Using Shared Library Types
// REMOVED: All pub use statements eliminated per cleanup requirements
// Use direct import: common::error::CommonError
/// Trading service specific error extensions
///
/// For cases where we need domain-specific error information
#[derive(Debug, thiserror::Error)]
pub enum TradingServiceError {
/// Shared library error with context
#[error("Trading service error: {0}")]
Common(#[from] common::error::CommonError),
/// `Order` validation failed with specific trading context
#[error("Order validation failed: {reason}")]
OrderValidation { reason: String },
/// Risk management violation with trading-specific details
#[error("Risk violation: {violation_type} - {message}")]
RiskViolation {
violation_type: String,
message: String,
},
/// ML model error with model context
#[error("ML model error: {model_name} - {message}")]
MLModel { model_name: String, message: String },
/// Database operation error
#[error("Database error: {source}")]
DatabaseError {
source: Box<dyn std::error::Error + Send + Sync>,
},
/// Configuration error
#[error("Configuration error: {message}")]
ConfigurationError { message: String },
/// Rate limit exceeded error
#[error("Rate limit exceeded: {message}")]
RateLimitExceeded { message: String },
/// Subscription timeout error
#[error("Subscription timeout: {message}")]
SubscriptionTimeout { message: String },
/// Subscription closed error
#[error("Subscription closed: {message}")]
SubscriptionClosed { message: String },
/// Internal service error
#[error("Internal error: {message}")]
Internal { message: String },
/// Timestamp conversion error
#[error("Invalid timestamp: {timestamp} - cannot convert to DateTime")]
TimestampConversion { timestamp: i64 },
/// Validation error
#[error("Validation error: {message}")]
ValidationError { message: String },
}
/// Result type for trading service operations
pub type TradingServiceResult<T> = std::result::Result<T, TradingServiceError>;
/// Convenience type alias using common result
pub type Result<T> = TradingServiceResult<T>;
/// Convert TradingServiceError to tonic::Status for gRPC responses
impl From<TradingServiceError> for tonic::Status {
fn from(err: TradingServiceError) -> Self {
match err {
TradingServiceError::Common(common_err) => {
// Leverage shared error to gRPC status conversion
match common_err {
common::error::CommonError::Validation(ref msg) => {
tonic::Status::invalid_argument(format!("Validation error: {}", msg))
},
common::error::CommonError::Configuration(ref msg) => {
tonic::Status::invalid_argument(format!("Configuration error: {}", msg))
},
common::error::CommonError::Network(ref msg) => {
tonic::Status::unavailable(format!("Network error: {}", msg))
},
common::error::CommonError::Database(ref db_err) => {
tonic::Status::internal(format!("Database error: {}", db_err))
},
common::error::CommonError::Service { category, message } => match category {
common::error::ErrorCategory::Authentication => {
tonic::Status::unauthenticated(message)
},
common::error::ErrorCategory::Resource => {
tonic::Status::not_found(message)
},
common::error::ErrorCategory::Validation => {
tonic::Status::invalid_argument(message)
},
_ => tonic::Status::internal(format!("{}: {}", category, message)),
},
common::error::CommonError::Timeout { actual_ms, max_ms } => {
tonic::Status::deadline_exceeded(format!(
"Operation timed out: {}ms (max: {}ms)",
actual_ms, max_ms
))
},
}
},
TradingServiceError::OrderValidation { reason } => {
tonic::Status::invalid_argument(format!("Order validation failed: {}", reason))
},
TradingServiceError::RiskViolation {
violation_type,
message,
} => tonic::Status::failed_precondition(format!(
"Risk violation {}: {}",
violation_type, message
)),
TradingServiceError::MLModel {
model_name,
message,
} => tonic::Status::internal(format!("ML model {} error: {}", model_name, message)),
TradingServiceError::DatabaseError { source } => {
tonic::Status::internal(format!("Database error: {}", source))
},
TradingServiceError::ConfigurationError { message } => {
tonic::Status::internal(format!("Configuration error: {}", message))
},
TradingServiceError::RateLimitExceeded { message } => {
tonic::Status::resource_exhausted(format!("Rate limit exceeded: {}", message))
},
TradingServiceError::SubscriptionTimeout { message } => {
tonic::Status::deadline_exceeded(format!("Subscription timeout: {}", message))
},
TradingServiceError::SubscriptionClosed { message } => {
tonic::Status::cancelled(format!("Subscription closed: {}", message))
},
TradingServiceError::Internal { message } => {
tonic::Status::internal(format!("Internal error: {}", message))
},
TradingServiceError::TimestampConversion { timestamp } => {
tonic::Status::invalid_argument(format!(
"Invalid timestamp conversion: {}",
timestamp
))
},
TradingServiceError::ValidationError { message } => {
tonic::Status::invalid_argument(format!("Validation error: {}", message))
},
}
}
}