2020-06-26 11:14:07 +00:00
|
|
|
use rocket::{
|
|
|
|
http::{ContentType, Status},
|
|
|
|
response,
|
|
|
|
response::Responder,
|
|
|
|
Outcome, Request, Response, State,
|
|
|
|
};
|
2020-06-24 08:25:28 +00:00
|
|
|
|
|
|
|
use slog;
|
2020-06-26 11:14:07 +00:00
|
|
|
use slog::Logger;
|
|
|
|
use std::io::Cursor;
|
2020-06-24 08:25:28 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Clone)]
|
|
|
|
pub enum ErrorCode {
|
|
|
|
InvalidCredentials,
|
|
|
|
MultipleAuthToken,
|
|
|
|
NoAuthToken,
|
|
|
|
AuthTokenCreationFailed,
|
|
|
|
MalformedAuthToken,
|
|
|
|
ResourceNotFound,
|
|
|
|
ResourceAlreadyExists,
|
|
|
|
DatabaseError,
|
|
|
|
InvalidData,
|
|
|
|
NotAuthorized,
|
|
|
|
CorruptResource,
|
|
|
|
LogicalConflict,
|
|
|
|
Unknown,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Clone)]
|
|
|
|
pub struct Error {
|
|
|
|
code: ErrorCode,
|
|
|
|
msg: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
pub fn new(code: ErrorCode) -> Error {
|
|
|
|
Error {
|
|
|
|
code,
|
|
|
|
msg: "".to_string(),
|
2020-06-26 11:14:07 +00:00
|
|
|
}
|
|
|
|
.set_msg()
|
2020-06-24 08:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn custom(code: ErrorCode, msg: String) -> Error {
|
2020-06-26 11:14:07 +00:00
|
|
|
Error { code, msg }
|
2020-06-24 08:25:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_status_code(&self) -> Status {
|
|
|
|
match self.code {
|
|
|
|
ErrorCode::InvalidCredentials => Status::Forbidden,
|
|
|
|
ErrorCode::ResourceNotFound => Status::NotFound,
|
|
|
|
ErrorCode::MultipleAuthToken => Status::Conflict,
|
|
|
|
ErrorCode::NoAuthToken => Status::Forbidden,
|
|
|
|
ErrorCode::AuthTokenCreationFailed => Status::InternalServerError,
|
|
|
|
ErrorCode::MalformedAuthToken => Status::Forbidden,
|
|
|
|
ErrorCode::ResourceAlreadyExists => Status::Conflict,
|
|
|
|
ErrorCode::DatabaseError => Status::InternalServerError,
|
|
|
|
ErrorCode::InvalidData => Status::BadRequest,
|
|
|
|
ErrorCode::NotAuthorized => Status::Forbidden,
|
|
|
|
ErrorCode::CorruptResource => Status::InternalServerError,
|
|
|
|
ErrorCode::LogicalConflict => Status::BadRequest,
|
2020-06-26 11:14:07 +00:00
|
|
|
ErrorCode::Unknown => Status::InternalServerError,
|
2020-06-24 08:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_msg(mut self) -> Self {
|
|
|
|
self.msg = match self.code.clone() {
|
|
|
|
ErrorCode::InvalidCredentials => "invalid credentials were provided".to_string(),
|
2020-06-26 11:14:07 +00:00
|
|
|
ErrorCode::MultipleAuthToken => {
|
|
|
|
"multiple authorization tokens were provided".to_string()
|
|
|
|
}
|
2020-06-24 08:25:28 +00:00
|
|
|
ErrorCode::NoAuthToken => "no authorization token was found".to_string(),
|
|
|
|
ErrorCode::AuthTokenCreationFailed => "authorization token creation failed".to_string(),
|
|
|
|
ErrorCode::MalformedAuthToken => "authorization token was malformed".to_string(),
|
|
|
|
ErrorCode::ResourceNotFound => "resource not found".to_string(),
|
|
|
|
ErrorCode::ResourceAlreadyExists => "the given resource already exists".to_string(),
|
|
|
|
ErrorCode::DatabaseError => "database error occured".to_string(),
|
|
|
|
ErrorCode::InvalidData => "invalid data provided".to_string(),
|
2020-06-26 11:14:07 +00:00
|
|
|
ErrorCode::NotAuthorized => {
|
|
|
|
"you are not authorized to perform the requested operation".to_string()
|
|
|
|
}
|
2020-06-24 08:25:28 +00:00
|
|
|
ErrorCode::CorruptResource => "requested resource was corrupted".to_string(),
|
2020-06-26 11:14:07 +00:00
|
|
|
ErrorCode::LogicalConflict => {
|
|
|
|
"the request logically conflicts with the existing data".to_string()
|
|
|
|
}
|
|
|
|
ErrorCode::Unknown => "unknown error occured".to_string(),
|
2020-06-24 08:25:28 +00:00
|
|
|
};
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'r> Responder<'r> for Error {
|
|
|
|
fn respond_to(self, request: &Request) -> response::Result<'r> {
|
|
|
|
let logger = request.guard::<State<Logger>>();
|
|
|
|
|
|
|
|
if let Outcome::Success(logger) = logger {
|
|
|
|
error!(logger, "{}", serde_json::to_string(&self).unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
Response::build()
|
|
|
|
.status(self.get_status_code())
|
|
|
|
.header(ContentType::JSON)
|
|
|
|
.sized_body(Cursor::new(serde_json::to_string(&self).unwrap()))
|
|
|
|
.ok()
|
|
|
|
}
|
2020-06-26 11:14:07 +00:00
|
|
|
}
|