1use thiserror::Error;
2
3#[derive(Debug, Error)]
5pub enum BootError {
6 #[error("module name cannot be empty")]
7 EmptyModuleName,
8 #[error("route path must start with '/': {0}")]
9 InvalidRoutePath(String),
10 #[error("host pattern is invalid: {0}")]
11 InvalidHostPattern(String),
12 #[error("route is already registered: {0}")]
13 DuplicateRoute(String),
14 #[error("route was not found: {0}")]
15 NotFound(String),
16 #[error("method is not allowed: {0}")]
17 MethodNotAllowed(String),
18 #[error("provider token is already registered: {0}")]
19 DuplicateProvider(String),
20 #[error("provider token is not registered: {0}")]
21 MissingProvider(String),
22 #[error("provider token has a different concrete type: {0}")]
23 ProviderTypeMismatch(String),
24 #[error("request was forbidden: {0}")]
25 Forbidden(String),
26 #[error("request was unauthorized: {0}")]
27 Unauthorized(String),
28 #[error("bad request: {0}")]
29 BadRequest(String),
30 #[error("payload is too large: {0}")]
31 PayloadTooLarge(String),
32 #[error("unsupported media type: {0}")]
33 UnsupportedMediaType(String),
34 #[error("not acceptable: {0}")]
35 NotAcceptable(String),
36 #[error("too many requests: {0}")]
37 TooManyRequests(String),
38 #[error("adapter error: {0}")]
39 Adapter(String),
40 #[error("internal error: {0}")]
41 Internal(String),
42 #[error("I/O error: {0}")]
43 Io(#[from] std::io::Error),
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub enum BootErrorKind {
49 EmptyModuleName,
50 InvalidRoutePath,
51 InvalidHostPattern,
52 DuplicateRoute,
53 NotFound,
54 MethodNotAllowed,
55 DuplicateProvider,
56 MissingProvider,
57 ProviderTypeMismatch,
58 Forbidden,
59 Unauthorized,
60 BadRequest,
61 PayloadTooLarge,
62 UnsupportedMediaType,
63 NotAcceptable,
64 TooManyRequests,
65 Adapter,
66 Internal,
67 Io,
68}
69
70impl BootError {
71 pub fn kind(&self) -> BootErrorKind {
73 match self {
74 Self::EmptyModuleName => BootErrorKind::EmptyModuleName,
75 Self::InvalidRoutePath(_) => BootErrorKind::InvalidRoutePath,
76 Self::InvalidHostPattern(_) => BootErrorKind::InvalidHostPattern,
77 Self::DuplicateRoute(_) => BootErrorKind::DuplicateRoute,
78 Self::NotFound(_) => BootErrorKind::NotFound,
79 Self::MethodNotAllowed(_) => BootErrorKind::MethodNotAllowed,
80 Self::DuplicateProvider(_) => BootErrorKind::DuplicateProvider,
81 Self::MissingProvider(_) => BootErrorKind::MissingProvider,
82 Self::ProviderTypeMismatch(_) => BootErrorKind::ProviderTypeMismatch,
83 Self::Forbidden(_) => BootErrorKind::Forbidden,
84 Self::Unauthorized(_) => BootErrorKind::Unauthorized,
85 Self::BadRequest(_) => BootErrorKind::BadRequest,
86 Self::PayloadTooLarge(_) => BootErrorKind::PayloadTooLarge,
87 Self::UnsupportedMediaType(_) => BootErrorKind::UnsupportedMediaType,
88 Self::NotAcceptable(_) => BootErrorKind::NotAcceptable,
89 Self::TooManyRequests(_) => BootErrorKind::TooManyRequests,
90 Self::Adapter(_) => BootErrorKind::Adapter,
91 Self::Internal(_) => BootErrorKind::Internal,
92 Self::Io(_) => BootErrorKind::Io,
93 }
94 }
95
96 pub fn http_status_code(&self) -> u16 {
98 match self {
99 Self::NotFound(_) => 404,
100 Self::MethodNotAllowed(_) => 405,
101 Self::Unauthorized(_) => 401,
102 Self::Forbidden(_) => 403,
103 Self::BadRequest(_) => 400,
104 Self::PayloadTooLarge(_) => 413,
105 Self::UnsupportedMediaType(_) => 415,
106 Self::NotAcceptable(_) => 406,
107 Self::TooManyRequests(_) => 429,
108 _ => 500,
109 }
110 }
111
112 pub fn http_response_message(&self) -> String {
114 match self {
115 Self::NotFound(message)
116 | Self::MethodNotAllowed(message)
117 | Self::Unauthorized(message)
118 | Self::Forbidden(message)
119 | Self::BadRequest(message)
120 | Self::PayloadTooLarge(message)
121 | Self::UnsupportedMediaType(message)
122 | Self::NotAcceptable(message)
123 | Self::TooManyRequests(message) => message.clone(),
124 error => error.to_string(),
125 }
126 }
127
128 pub(crate) fn clone_for_filter(&self) -> Self {
129 match self {
130 Self::EmptyModuleName => Self::EmptyModuleName,
131 Self::InvalidRoutePath(message) => Self::InvalidRoutePath(message.clone()),
132 Self::InvalidHostPattern(message) => Self::InvalidHostPattern(message.clone()),
133 Self::DuplicateRoute(message) => Self::DuplicateRoute(message.clone()),
134 Self::NotFound(message) => Self::NotFound(message.clone()),
135 Self::MethodNotAllowed(message) => Self::MethodNotAllowed(message.clone()),
136 Self::DuplicateProvider(message) => Self::DuplicateProvider(message.clone()),
137 Self::MissingProvider(message) => Self::MissingProvider(message.clone()),
138 Self::ProviderTypeMismatch(message) => Self::ProviderTypeMismatch(message.clone()),
139 Self::Forbidden(message) => Self::Forbidden(message.clone()),
140 Self::Unauthorized(message) => Self::Unauthorized(message.clone()),
141 Self::BadRequest(message) => Self::BadRequest(message.clone()),
142 Self::PayloadTooLarge(message) => Self::PayloadTooLarge(message.clone()),
143 Self::UnsupportedMediaType(message) => Self::UnsupportedMediaType(message.clone()),
144 Self::NotAcceptable(message) => Self::NotAcceptable(message.clone()),
145 Self::TooManyRequests(message) => Self::TooManyRequests(message.clone()),
146 Self::Adapter(message) => Self::Adapter(message.clone()),
147 Self::Internal(message) => Self::Internal(message.clone()),
148 Self::Io(error) => Self::Io(std::io::Error::new(error.kind(), error.to_string())),
149 }
150 }
151}