tenebrous-sheets/src/errors.rs

83 lines
2.4 KiB
Rust
Raw Normal View History

2020-12-01 21:32:16 +00:00
use rocket::http::Status;
use rocket::request::Request;
use rocket::response::status;
use rocket::response::{self, Responder};
use rocket_contrib::templates::Template;
use std::collections::HashMap;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("resource not found")]
NotFound,
#[error("you must be logged in")]
NotLoggedIn,
#[error("you do not have permission to access this")]
NoPermission,
#[error("query error: {0}")]
QueryError(#[from] diesel::result::Error),
#[error("serialization error: {0}")]
SerializationError(#[from] prost::EncodeError),
2020-12-01 21:32:16 +00:00
}
#[derive(Error, Debug)]
#[error("internal eror")]
pub struct SensitiveError(Error);
2020-12-01 21:32:16 +00:00
impl Error {
fn is_sensitive(&self) -> bool {
use Error::*;
match self {
QueryError(_) => true,
_ => false,
}
}
}
impl<'r> Responder<'r> for Error {
fn respond_to(self, req: &Request) -> response::Result<'r> {
log::error!("error: {0}", self.to_string());
2020-12-01 21:32:16 +00:00
//Hide sensitive error information
let message: String = if self.is_sensitive() {
"internal error".into()
} else {
self.to_string()
};
let mut context = HashMap::new();
context.insert("message", message);
let resp = Template::render("error", context).respond_to(req)?;
use Error::*;
match self {
NotFound => status::NotFound(resp).respond_to(req),
NotLoggedIn => status::Forbidden(Some(resp)).respond_to(req),
NoPermission => status::Forbidden(Some(resp)).respond_to(req),
_ => status::Custom(Status::InternalServerError, resp).respond_to(req),
}
}
}
impl<'r> Responder<'r> for SensitiveError {
fn respond_to(self, req: &Request) -> response::Result<'r> {
log::error!("sensitive error: {0}", self.0.to_string());
let message: String = self.to_string();
let mut context = HashMap::new();
context.insert("message", message);
let resp = Template::render("error", context).respond_to(req)?;
use Error::*;
match self.0 {
NotFound => status::NotFound(resp).respond_to(req),
NotLoggedIn => status::Forbidden(Some(resp)).respond_to(req),
NoPermission => status::Forbidden(Some(resp)).respond_to(req),
_ => status::Custom(Status::InternalServerError, resp).respond_to(req),
}
}
}