mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 13:36:59 +00:00
97 lines
3.2 KiB
Rust
97 lines
3.2 KiB
Rust
use json;
|
|
use rocket::http::{ContentType, Status};
|
|
use rocket::request::Request;
|
|
use rocket::response::{self, Responder, Response};
|
|
use serde::Serialize;
|
|
use snafu::Snafu;
|
|
use std::io::Cursor;
|
|
use validator::ValidationErrors;
|
|
|
|
#[derive(Serialize, Debug, Snafu)]
|
|
#[serde(tag = "type")]
|
|
pub enum Error {
|
|
#[snafu(display("This error has not been labelled."))]
|
|
LabelMe,
|
|
|
|
// ? Onboarding related errors.
|
|
#[snafu(display("Already finished onboarding."))]
|
|
AlreadyOnboarded,
|
|
|
|
// ? User related errors.
|
|
#[snafu(display("Username has already been taken."))]
|
|
UsernameTaken,
|
|
#[snafu(display("This user does not exist!"))]
|
|
UnknownUser,
|
|
#[snafu(display("Already friends with this user."))]
|
|
AlreadyFriends,
|
|
#[snafu(display("Already sent a request to this user."))]
|
|
AlreadySentRequest,
|
|
#[snafu(display("You have blocked this user."))]
|
|
Blocked,
|
|
#[snafu(display("You have been blocked by this user."))]
|
|
BlockedByOther,
|
|
#[snafu(display("Not friends with target user."))]
|
|
NotFriends,
|
|
|
|
// ? Channel related errors.
|
|
#[snafu(display("Cannot edit someone else's message."))]
|
|
CannotEditMessage,
|
|
#[snafu(display("Group size is too large."))]
|
|
GroupTooLarge { max: usize },
|
|
|
|
// ? General errors.
|
|
#[snafu(display("Failed to validate fields."))]
|
|
FailedValidation { error: ValidationErrors },
|
|
#[snafu(display("Encountered a database error."))]
|
|
DatabaseError {
|
|
operation: &'static str,
|
|
with: &'static str,
|
|
},
|
|
#[snafu(display("Internal server error."))]
|
|
InternalError,
|
|
#[snafu(display("Already created an object with this nonce."))]
|
|
DuplicateNonce,
|
|
#[snafu(display("This request had no effect."))]
|
|
NoEffect,
|
|
}
|
|
|
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
|
|
/// HTTP response builder for Error enum
|
|
impl<'r> Responder<'r, 'static> for Error {
|
|
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
|
|
let status = match self {
|
|
Error::LabelMe => Status::InternalServerError,
|
|
|
|
Error::AlreadyOnboarded => Status::Forbidden,
|
|
|
|
Error::UnknownUser => Status::NotFound,
|
|
Error::UsernameTaken => Status::Conflict,
|
|
Error::AlreadyFriends => Status::Conflict,
|
|
Error::AlreadySentRequest => Status::Conflict,
|
|
Error::Blocked => Status::Conflict,
|
|
Error::BlockedByOther => Status::Forbidden,
|
|
Error::NotFriends => Status::Forbidden,
|
|
|
|
Error::CannotEditMessage => Status::Forbidden,
|
|
Error::GroupTooLarge { .. } => Status::Forbidden,
|
|
|
|
Error::FailedValidation { .. } => Status::UnprocessableEntity,
|
|
Error::DatabaseError { .. } => Status::InternalServerError,
|
|
Error::InternalError => Status::InternalServerError,
|
|
Error::DuplicateNonce => Status::Conflict,
|
|
Error::NoEffect => Status::Ok,
|
|
};
|
|
|
|
// Serialize the error data structure into JSON.
|
|
let string = json!(self).to_string();
|
|
|
|
// Build and send the request.
|
|
Response::build()
|
|
.sized_body(string.len(), Cursor::new(string))
|
|
.header(ContentType::new("application", "json"))
|
|
.status(status)
|
|
.ok()
|
|
}
|
|
}
|