/// Errors produced by sunbeam-net. #[derive(Debug, thiserror::Error)] pub enum Error { #[error("noise handshake failed: {0}")] Noise(String), #[error("control protocol error: {0}")] Control(String), #[error("wireguard error: {0}")] WireGuard(String), #[error("DERP relay error: {0}")] Derp(String), #[error("authentication failed: {0}")] Auth(String), #[error("daemon error: {0}")] Daemon(String), #[error("IPC error: {0}")] Ipc(String), #[error("{context}: {source}")] Io { context: String, #[source] source: std::io::Error, }, #[error("{0}")] Json(#[from] serde_json::Error), #[error("connection closed")] ConnectionClosed, #[error("{0}")] Other(String), } pub type Result = std::result::Result; impl From for Error { fn from(e: h2::Error) -> Self { Error::Control(e.to_string()) } } /// Extension trait for adding context to `Result` types. pub trait ResultExt { fn ctx(self, context: &str) -> Result; fn with_ctx String>(self, f: F) -> Result; } impl ResultExt for std::result::Result { fn ctx(self, context: &str) -> Result { self.map_err(|source| Error::Io { context: context.to_string(), source, }) } fn with_ctx String>(self, f: F) -> Result { self.map_err(|source| Error::Io { context: f(), source, }) } } impl ResultExt for Result { fn ctx(self, context: &str) -> Result { self.map_err(|e| Error::Other(format!("{context}: {e}"))) } fn with_ctx String>(self, f: F) -> Result { self.map_err(|e| Error::Other(format!("{}: {e}", f()))) } }