use std::time::Duration;
use thiserror::Error;
use tokio::sync::mpsc;
#[derive(Error, Debug, Default)]
pub enum DriverError {
#[error("Service unavailable")]
#[default]
ServiceUnavailable,
#[error("Validation error: {0}")]
ValidationError(String),
#[error("Execution error: {0}")]
ExecutionError(String),
#[error("Configuration error: {0}")]
ConfigurationError(String),
#[error("Initialization error: {0}")]
InitializationError(String),
#[error("Invalid state error: {0}")]
InvalidStateError(String),
#[error("Codec error: {0}")]
CodecError(String),
#[error("Read/Write timeout")]
Timeout(Duration),
#[error("Planner error: {0}")]
PlannerError(String),
#[error("Session error: {0}")]
SessionError(String),
#[error("Subscription error: {0}")]
SubscriptionError(String),
#[error("Northward error: {0}")]
NorthwardError(String),
#[error("LoadError error: {0}")]
LoadError(String),
#[error("Invalid entity: {0}")]
InvalidEntity(String),
}
#[derive(Error, Debug)]
pub enum NorthwardError {
#[error("Authentication failed for platform '{platform}': {reason}")]
AuthenticationFailed { platform: String, reason: String },
#[error("Failed to publish message to platform '{platform}': {reason}")]
PublishFailed { platform: String, reason: String },
#[error("Failed to subscribe to topic '{topic}' on platform '{platform}': {reason}")]
SubscriptionFailed {
platform: String,
topic: String,
reason: String,
},
#[error("Serialization failed: {reason}")]
SerializationError { reason: String },
#[error("Deserialization failed: {reason}")]
DeserializationError { reason: String },
#[error("Configuration error: {message}")]
ConfigurationError { message: String },
#[error("Data send error: {message}")]
DataSendError { message: String },
#[error("Operation timed out after {timeout_ms}ms: {operation}")]
Timeout { timeout_ms: u64, operation: String },
#[error("Circuit breaker is open for platform '{platform}'")]
CircuitBreakerOpen { platform: String },
#[error("Platform '{platform}' not found or not configured")]
PlatformNotFound { platform: String },
#[error("Invalid message format: {reason}")]
InvalidMessageFormat { reason: String },
#[error("TLS error for platform '{platform}': {reason}")]
TlsError { platform: String, reason: String },
#[error("MQTT protocol error: {reason}")]
MqttError { reason: String },
#[error("Resource exhausted: {resource}")]
ResourceExhausted { resource: String },
#[error("Operation not supported: {operation} for platform '{platform}'")]
OperationNotSupported { operation: String, platform: String },
#[error("Device provision failed for platform '{platform}': {reason}")]
ProvisionFailed { platform: String, reason: String },
#[error("Device credentials not found for platform '{platform}'")]
CredentialsNotFound { platform: String },
#[error("Device provision timeout after {timeout_ms}ms for platform '{platform}'")]
ProvisionTimeout { platform: String, timeout_ms: u64 },
#[error("Not connected to platform - operation requires active connection")]
NotConnected,
#[error("Invalid provision configuration for platform '{platform}': {reason}")]
InvalidProvisionConfig { platform: String, reason: String },
#[error("Northward manager queue is full (capacity reached)")]
QueueFull,
#[error("Load error: {0}")]
LoadError(String),
#[error("Not found: {entity}")]
NotFound { entity: String },
#[error("Gateway error: {reason}")]
GatewayError { reason: String },
#[error("Validation failed: {reason}")]
ValidationFailed { reason: String },
#[error("Runtime error: {reason}")]
RuntimeError { reason: String },
#[error("Storage error: {reason}")]
StorageError { reason: String },
}
impl From<serde_json::Error> for NorthwardError {
fn from(err: serde_json::Error) -> Self {
NorthwardError::SerializationError {
reason: err.to_string(),
}
}
}
impl<T> From<mpsc::error::SendError<T>> for NorthwardError {
fn from(err: mpsc::error::SendError<T>) -> Self {
NorthwardError::DataSendError {
message: format!("Channel send failed: {err}"),
}
}
}