use axum::{
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use serde_json::json;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, WebError>;
#[derive(Error, Debug)]
pub enum WebError {
#[error("Storage error: {0}")]
Storage(String),
#[error("Orchestrator error: {0}")]
Orchestrator(String),
#[error("Invalid request: {0}")]
InvalidRequest(String),
#[error("Not found: {0}")]
NotFound(String),
#[error("Server error: {0}")]
ServerStart(String),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("WebSocket error: {0}")]
WebSocket(String),
#[error("Configuration error: {0}")]
Config(String),
}
impl IntoResponse for WebError {
fn into_response(self) -> Response {
let (status, error_message) = match &self {
WebError::Storage(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
WebError::Orchestrator(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
WebError::InvalidRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
WebError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
WebError::ServerStart(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
WebError::Serialization(_) => (StatusCode::BAD_REQUEST, "Invalid JSON".to_string()),
WebError::WebSocket(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
WebError::Config(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
};
let body = Json(json!({
"success": false,
"error": error_message,
}));
(status, body).into_response()
}
}
impl From<nexus_core::NexusError> for WebError {
fn from(err: nexus_core::NexusError) -> Self {
match err {
nexus_core::NexusError::Storage(msg) => WebError::Storage(msg),
nexus_core::NexusError::MemoryNotFound(id) => {
WebError::NotFound(format!("Memory not found: {}", id))
}
nexus_core::NexusError::NamespaceNotFound(name) => {
WebError::NotFound(format!("Namespace not found: {}", name))
}
nexus_core::NexusError::InvalidInput(msg) => WebError::InvalidRequest(msg),
nexus_core::NexusError::InvalidConfig(msg) => WebError::InvalidRequest(msg),
_ => WebError::Storage(err.to_string()),
}
}
}
impl From<nexus_orchestrator::OrchestratorError> for WebError {
fn from(err: nexus_orchestrator::OrchestratorError) -> Self {
WebError::Orchestrator(err.to_string())
}
}
impl From<sqlx::Error> for WebError {
fn from(err: sqlx::Error) -> Self {
WebError::Storage(err.to_string())
}
}