Files
locutus-server/src/error.rs

146 lines
4.0 KiB
Rust

use std::fmt;
#[derive(Copy, Clone, Debug)]
pub enum Kind {
InvalidEndpointError,
JsonParseError,
DatabaseConnectionError,
DatabaseError,
HttpRequestParseError,
IoError,
WebSocketError,
NotImplementedError,
UsimpProtocolError,
}
#[derive(Copy, Clone, Debug)]
pub enum Class {
ClientError,
ServerError,
}
#[derive(Debug)]
pub struct Error {
kind: Kind,
msg: Option<String>,
desc: Option<String>,
class: Class,
}
impl Error {
pub fn new(kind: Kind, class: Class) -> Self {
Error {
kind,
msg: None,
desc: None,
class,
}
}
pub fn class(&self) -> &Class {
&self.class
}
pub fn set_msg(mut self, msg: String) -> Self {
self.msg = Some(msg);
self
}
pub fn msg(&self) -> &str {
match &self.msg {
Some(msg) => msg.as_str(),
None => match self.kind {
Kind::InvalidEndpointError => "Invalid endpoint",
Kind::JsonParseError => "Unable to parse JSON data",
Kind::DatabaseConnectionError => "Unable to connect to database",
Kind::DatabaseError => "Database error",
Kind::HttpRequestParseError => "Unable to parse http request",
Kind::IoError => "IO error",
Kind::WebSocketError => "WebSocket protocol error",
Kind::NotImplementedError => "Not yet implemented",
Kind::UsimpProtocolError => "USIMP protocol error",
},
}
}
pub fn set_desc(mut self, desc: String) -> Self {
self.desc = Some(desc);
self
}
pub fn desc(&self) -> Option<&str> {
match &self.desc {
Some(desc) => Some(desc.as_str()),
None => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut error = match self.kind {
Kind::InvalidEndpointError => "invalid endpoint",
Kind::JsonParseError => "unable to parse json data",
Kind::DatabaseConnectionError => "unable to connect to database",
Kind::DatabaseError => "database error",
Kind::HttpRequestParseError => "unable to parse http request",
Kind::IoError => "io error",
Kind::WebSocketError => "websocket protocol error",
Kind::NotImplementedError => "not yet implemented",
Kind::UsimpProtocolError => "usimp protocol error",
}
.to_string();
if let Some(desc) = &self.desc {
error += ": ";
error += desc;
}
write!(f, "{}", error)
}
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
Error {
kind: Kind::IoError,
msg: Some(error.to_string()),
desc: Some(error.to_string()),
class: Class::ClientError,
}
}
}
impl From<serde_json::Error> for Error {
fn from(error: serde_json::Error) -> Self {
Error {
kind: Kind::JsonParseError,
msg: Some("Unable to parse JSON data".to_string()),
desc: Some(error.to_string()),
class: Class::ClientError,
}
}
}
impl From<r2d2::Error> for Error {
fn from(error: r2d2::Error) -> Self {
Error {
kind: Kind::DatabaseConnectionError,
msg: Some("Unable to connect to database".to_string()),
desc: Some(error.to_string()),
class: Class::ServerError,
}
}
}
impl From<r2d2_postgres::postgres::Error> for Error {
fn from(error: r2d2_postgres::postgres::Error) -> Self {
// format: "db error: ERROR ..."
let msg = error.to_string().split(":").skip(1).collect::<String>();
Error {
kind: Kind::DatabaseError,
msg: Some("Database error".to_string()),
desc: Some(msg.trim().to_string()),
class: Class::ServerError,
}
}
}