use crate::{ request::EventRequest, response::{EventResponse, EventResponseBuilder, StatusCode}, }; use dyn_clone::DynClone; use std::{fmt, option::NoneError}; use tokio::sync::mpsc::error::SendError; #[cfg(feature = "use_serde")] use serde::{Serialize, Serializer}; pub trait Error: fmt::Debug + fmt::Display + DynClone { fn status_code(&self) -> StatusCode; fn as_response(&self) -> EventResponse { EventResponse::new(self.status_code()) } } dyn_clone::clone_trait_object!(Error); impl From for SystemError { fn from(err: T) -> SystemError { SystemError { inner: Box::new(err), } } } #[derive(Clone)] pub struct SystemError { inner: Box, } impl SystemError { pub fn inner_error(&self) -> &dyn Error { self.inner.as_ref() } } impl fmt::Display for SystemError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) } } impl fmt::Debug for SystemError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", &self.inner) } } impl std::error::Error for SystemError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } fn cause(&self) -> Option<&dyn std::error::Error> { None } } impl From> for SystemError { fn from(err: SendError) -> Self { InternalError { inner: format!("{}", err), } .into() } } impl From for SystemError { fn from(s: NoneError) -> Self { InternalError { inner: format!("Unexpected none: {:?}", s), } .into() } } impl From for SystemError { fn from(s: String) -> Self { InternalError { inner: s }.into() } } impl From for EventResponse { fn from(err: SystemError) -> Self { err.inner_error().as_response() } } #[derive(Clone)] pub struct InternalError { inner: T, } impl InternalError { pub fn new(inner: T) -> Self { InternalError { inner } } } impl fmt::Debug for InternalError where T: fmt::Debug + 'static + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.inner, f) } } impl fmt::Display for InternalError where T: fmt::Debug + fmt::Display + 'static + Clone, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.inner, f) } } impl Error for InternalError where T: fmt::Debug + fmt::Display + 'static + Clone, { fn status_code(&self) -> StatusCode { StatusCode::Err } fn as_response(&self) -> EventResponse { let error = InternalError { inner: format!("{}", self.inner), } .into(); EventResponseBuilder::Err().error(error).build() } } #[cfg(feature = "use_serde")] impl Serialize for SystemError { fn serialize(&self, serializer: S) -> Result<::Ok, ::Error> where S: Serializer, { serializer.serialize_str(&format!("{}", self)) } }