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>;
|
|
|
|
}
|
|
|
|
|
2021-01-06 08:21:37 +00:00
|
|
|
pub(crate) trait OptionExt<T> {
|
|
|
|
fn req(self) -> Result<T, Error>;
|
|
|
|
}
|
|
|
|
|
2020-12-16 02:40:41 +00:00
|
|
|
#[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),
|
|
|
|
|
2021-01-06 08:21:37 +00:00
|
|
|
#[error("{0}")]
|
|
|
|
Profiles(#[from] hyaenidae_profiles::Error),
|
|
|
|
|
2020-12-16 02:40:41 +00:00
|
|
|
#[error("{0}")]
|
|
|
|
Render(std::io::Error),
|
|
|
|
|
2021-01-06 08:21:37 +00:00
|
|
|
#[error("{0}")]
|
|
|
|
Sled(#[from] sled::Error),
|
|
|
|
|
2020-12-16 02:40:41 +00:00
|
|
|
#[error("{0}")]
|
|
|
|
Minify(String),
|
2021-01-06 08:21:37 +00:00
|
|
|
|
|
|
|
#[error("Required data was not present")]
|
|
|
|
Required,
|
2020-12-16 02:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ResponseError for StateError {
|
|
|
|
fn status_code(&self) -> StatusCode {
|
|
|
|
match self.error {
|
2021-01-06 08:21:37 +00:00
|
|
|
Error::Render(_)
|
|
|
|
| Error::Minify(_)
|
|
|
|
| Error::Accounts(_)
|
|
|
|
| Error::Profiles(_)
|
|
|
|
| Error::Sled(_)
|
|
|
|
| Error::Required => StatusCode::INTERNAL_SERVER_ERROR,
|
2020-12-16 02:40:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-06 08:21:37 +00:00
|
|
|
impl<T> OptionExt<T> for Option<T> {
|
|
|
|
fn req(self) -> Result<T, Error> {
|
|
|
|
self.ok_or_else(|| Error::Required)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-16 02:40:41 +00:00
|
|
|
impl From<minify_html::Error> for Error {
|
|
|
|
fn from(e: minify_html::Error) -> Self {
|
|
|
|
Error::Minify(format!("{:?}", e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-06 08:21:37 +00:00
|
|
|
impl From<hyaenidae_profiles::store::StoreError> for Error {
|
|
|
|
fn from(e: hyaenidae_profiles::store::StoreError) -> Self {
|
|
|
|
Error::Profiles(From::from(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<hyaenidae_profiles::apub::StoreError> for Error {
|
|
|
|
fn from(e: hyaenidae_profiles::apub::StoreError) -> Self {
|
|
|
|
Error::Profiles(From::from(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-16 02:40:41 +00:00
|
|
|
impl State {
|
|
|
|
pub(crate) fn error<E>(&self, error: E) -> StateError
|
|
|
|
where
|
|
|
|
Error: From<E>,
|
|
|
|
{
|
|
|
|
StateError {
|
|
|
|
state: self.clone(),
|
|
|
|
error: error.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|