use orcs_runtime::{ChannelError, EngineError, StorageError};
use orcs_types::ErrorCode;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum AppError {
#[error("Channel error: {0}")]
Channel(#[from] ChannelError),
#[error("Engine error: {0}")]
Engine(#[from] EngineError),
#[error("Config error: {0}")]
Config(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Not initialized: {0}")]
NotInitialized(String),
#[error("Storage error: {0}")]
Storage(#[from] StorageError),
}
impl ErrorCode for AppError {
fn code(&self) -> &'static str {
match self {
Self::Channel(e) => e.code(),
Self::Engine(e) => e.code(),
Self::Config(_) => "APP_CONFIG_ERROR",
Self::Io(_) => "APP_IO_ERROR",
Self::NotInitialized(_) => "APP_NOT_INITIALIZED",
Self::Storage(_) => "APP_STORAGE_ERROR",
}
}
fn is_recoverable(&self) -> bool {
match self {
Self::Channel(e) => e.is_recoverable(),
Self::Engine(e) => e.is_recoverable(),
Self::Config(_) => false,
Self::Io(_) => true,
Self::NotInitialized(_) => false,
Self::Storage(_) => true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use orcs_types::ChannelId;
#[test]
fn channel_error_converts() {
let err = ChannelError::NotFound(ChannelId::new());
let app_err: AppError = err.into();
assert!(matches!(app_err, AppError::Channel(_)));
}
#[test]
fn error_codes() {
let err = AppError::Config("test".into());
assert_eq!(err.code(), "APP_CONFIG_ERROR");
assert!(!err.is_recoverable());
}
}