tenebrous-sheets/src/errors.rs

64 lines
1.7 KiB
Rust

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),
#[error("deserialization error: {0}")]
DeserializationError(#[from] prost::DecodeError),
}
impl Error {
fn is_sensitive(&self) -> bool {
use Error::*;
match self {
QueryError(_) => true,
_ => false,
}
}
}
#[rocket::async_trait]
impl<'r> Responder<'r, 'static> for Error {
fn respond_to(self, req: &Request) -> response::Result<'static> {
log::error!("error: {0}", self.to_string());
//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),
}
}
}