use axum::{ extract::ws::Message, http::StatusCode, response::{IntoResponse, Response}, Json, }; use serde_json::json; use thiserror::Error; pub type Result = std::result::Result; #[derive(Error, Debug)] pub enum Error { #[error("Zone Error: {0:?}")] Zone(String), #[error("Script Error: {0:?}")] Script(String), #[error("Container Error: {0:?}")] Container(String), #[error("WebSocket Error: {0:?}")] WebSocket(String), #[error("Container not found")] NotFound, #[error("Missing initialization message")] WebSocketMissingInit, #[error("ZFS Error: {source:?}")] ZFS { #[from] source: zone_zfs::Error, }, #[error("NSpawn Error: {source:?}")] Nspawn { #[from] source: zone_nspawn::Error, }, #[error("Core Error: {source:?}")] Core { #[from] source: zone_core::Error, }, #[error("Config Error: {source:?}")] Config { #[from] source: figment::Error, }, #[error("Axum Error: {source:?}")] Axum { #[from] source: axum::Error, }, #[error("IO Error: {source:?}")] IO { #[from] source: std::io::Error, }, #[error("Json Error: {source:?}")] Json { #[from] source: serde_json::error::Error, }, #[error("Send Error: {source:?}")] Send { #[from] source: tokio::sync::mpsc::error::SendError, }, #[error(transparent)] Other(#[from] anyhow::Error), } impl IntoResponse for Error { fn into_response(self) -> Response { let (status, error_message) = match self { Error::Container(source) => (StatusCode::NOT_FOUND, source), err => (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", err)), }; let body = Json(json!({ "error": error_message, })); (status, body).into_response() } }