use crate::{Responder, Response, Result};
use hyper::StatusCode;
use std::error::Error as StdError;
use std::fmt::Formatter;
pub enum Error {
Http(Response),
Internal(anyhow::Error),
}
impl Error {
pub(crate) fn into_std(self) -> Box<dyn StdError + Send + Sync + 'static> {
match self {
Error::Http(_) => panic!("http error??!"),
Error::Internal(err) => err.into(),
}
}
pub fn http(resp: impl Responder) -> Self {
match resp.into_response() {
Ok(r) => Self::Http(r),
Err(e) => e,
}
}
pub fn bad_request(resp: impl Responder) -> Self {
Self::http((StatusCode::BAD_REQUEST, resp))
}
}
impl Responder for Error {
fn into_response(self) -> Result<Response> {
match self {
Error::Http(resp) => Ok(resp),
Error::Internal(_err) => {
Ok(Response::status(StatusCode::INTERNAL_SERVER_ERROR))
}
}
}
}
impl<E> From<E> for Error
where
E: Into<anyhow::Error>,
{
fn from(e: E) -> Self {
Error::Internal(e.into())
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Error::Internal(err) => f
.debug_struct("Error::Internal")
.field("inner", err)
.finish(),
Error::Http(resp) => f.debug_struct("Error::Http").field("inner", resp).finish(),
}
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Error::Internal(err) => write!(f, "Internal Error: {:?}", err),
Error::Http(resp) => write!(f, "{:?}", resp),
}
}
}