hyaenidae/server/src/error.rs

74 lines
1.7 KiB
Rust
Raw Normal View History

2020-12-16 02:40:41 +00:00
use crate::{rendered, State};
use actix_web::{http::StatusCode, HttpResponse, ResponseError};
pub(crate) trait ResultExt<T> {
fn state(self, state: &State) -> Result<T, StateError>;
}
#[derive(Debug, thiserror::Error)]
#[error("{error}")]
pub(crate) struct StateError {
state: State,
error: Error,
}
#[derive(Debug, thiserror::Error)]
pub(crate) enum Error {
#[error("{0}")]
Accounts(#[from] hyaenidae_accounts::Error),
#[error("{0}")]
Render(std::io::Error),
#[error("{0}")]
Minify(String),
}
impl ResponseError for StateError {
fn status_code(&self) -> StatusCode {
match self.error {
Error::Render(_) | Error::Minify(_) | Error::Accounts(_) => {
StatusCode::INTERNAL_SERVER_ERROR
}
}
}
fn error_response(&self) -> HttpResponse {
match rendered(HttpResponse::build(self.status_code()), |cursor| {
crate::templates::error(cursor, self.error.to_string())
}) {
Ok(res) => res,
Err(_) => HttpResponse::build(self.status_code())
.content_type(mime::TEXT_PLAIN.essence_str())
.body(self.error.to_string()),
}
}
}
impl<T, E> ResultExt<T> for Result<T, E>
where
Error: From<E>,
{
fn state(self, state: &State) -> Result<T, StateError> {
self.map_err(|e| state.error(e))
}
}
impl From<minify_html::Error> for Error {
fn from(e: minify_html::Error) -> Self {
Error::Minify(format!("{:?}", e))
}
}
impl State {
pub(crate) fn error<E>(&self, error: E) -> StateError
where
Error: From<E>,
{
StateError {
state: self.clone(),
error: error.into(),
}
}
}