1use crate::{request::RequestError, route::RouteError, socket::SocketError, StatusCode};
8use config::ConfigError;
9use serde::{de::DeserializeOwned, Deserialize, Serialize};
10use snafu::Snafu;
11use std::fmt::Display;
12use std::io::Error as IoError;
13
14pub trait Error: std::error::Error + Serialize + DeserializeOwned + Send + Sync + 'static {
26 fn catch_all(status: StatusCode, msg: String) -> Self;
27 fn status(&self) -> StatusCode;
28
29 fn from_io_error(source: IoError) -> Self {
30 Self::catch_all(StatusCode::INTERNAL_SERVER_ERROR, source.to_string())
31 }
32
33 fn from_config_error(source: ConfigError) -> Self {
34 Self::catch_all(StatusCode::INTERNAL_SERVER_ERROR, source.to_string())
35 }
36
37 fn from_route_error<E: Display>(source: RouteError<E>) -> Self {
38 Self::catch_all(source.status(), source.to_string())
39 }
40
41 fn from_request_error(source: RequestError) -> Self {
42 Self::catch_all(StatusCode::BAD_REQUEST, source.to_string())
43 }
44
45 fn from_socket_error<E: Display>(source: SocketError<E>) -> Self {
46 Self::catch_all(source.status(), source.to_string())
47 }
48
49 fn into_tide_error(self) -> tide::Error {
50 tide::Error::new(self.status(), self)
51 }
52
53 fn from_server_error(source: tide::Error) -> Self {
54 match source.downcast::<Self>() {
55 Ok(err) => err,
56 Err(source) => Self::catch_all(source.status().into(), source.to_string()),
57 }
58 }
59}
60
61#[derive(Clone, Debug, Snafu, Serialize, Deserialize, PartialEq, Eq)]
67#[snafu(display("Error {}: {}", status, message))]
68pub struct ServerError {
69 pub status: StatusCode,
70 pub message: String,
71}
72
73impl Error for ServerError {
74 fn catch_all(status: StatusCode, message: String) -> Self {
75 Self { status, message }
76 }
77
78 fn status(&self) -> StatusCode {
79 self.status
80 }
81}
82
83impl From<IoError> for ServerError {
84 fn from(source: IoError) -> Self {
85 Self::from_io_error(source)
86 }
87}
88
89impl From<ConfigError> for ServerError {
90 fn from(source: ConfigError) -> Self {
91 Self::from_config_error(source)
92 }
93}
94
95impl<E: Display> From<RouteError<E>> for ServerError {
96 fn from(source: RouteError<E>) -> Self {
97 Self::from_route_error(source)
98 }
99}
100
101impl From<RequestError> for ServerError {
102 fn from(source: RequestError) -> Self {
103 Self::from_request_error(source)
104 }
105}
106
107impl<E: Display> From<SocketError<E>> for ServerError {
108 fn from(source: SocketError<E>) -> Self {
109 Self::from_socket_error(source)
110 }
111}