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("route is already registered: {0}")]
11 DuplicateRoute(String),
12 #[error("route was not found: {0}")]
13 NotFound(String),
14 #[error("method is not allowed: {0}")]
15 MethodNotAllowed(String),
16 #[error("provider token is already registered: {0}")]
17 DuplicateProvider(String),
18 #[error("provider token is not registered: {0}")]
19 MissingProvider(String),
20 #[error("provider token has a different concrete type: {0}")]
21 ProviderTypeMismatch(String),
22 #[error("request was forbidden: {0}")]
23 Forbidden(String),
24 #[error("request was unauthorized: {0}")]
25 Unauthorized(String),
26 #[error("bad request: {0}")]
27 BadRequest(String),
28 #[error("payload is too large: {0}")]
29 PayloadTooLarge(String),
30 #[error("unsupported media type: {0}")]
31 UnsupportedMediaType(String),
32 #[error("not acceptable: {0}")]
33 NotAcceptable(String),
34 #[error("adapter error: {0}")]
35 Adapter(String),
36 #[error("internal error: {0}")]
37 Internal(String),
38 #[error("I/O error: {0}")]
39 Io(#[from] std::io::Error),
40}
41
42impl BootError {
43 pub fn http_status_code(&self) -> u16 {
45 match self {
46 Self::NotFound(_) => 404,
47 Self::MethodNotAllowed(_) => 405,
48 Self::Unauthorized(_) => 401,
49 Self::Forbidden(_) => 403,
50 Self::BadRequest(_) => 400,
51 Self::PayloadTooLarge(_) => 413,
52 Self::UnsupportedMediaType(_) => 415,
53 Self::NotAcceptable(_) => 406,
54 _ => 500,
55 }
56 }
57
58 pub fn http_response_message(&self) -> String {
60 match self {
61 Self::NotFound(message)
62 | Self::MethodNotAllowed(message)
63 | Self::Unauthorized(message)
64 | Self::Forbidden(message)
65 | Self::BadRequest(message)
66 | Self::PayloadTooLarge(message)
67 | Self::UnsupportedMediaType(message)
68 | Self::NotAcceptable(message) => message.clone(),
69 error => error.to_string(),
70 }
71 }
72
73 pub(crate) fn clone_for_filter(&self) -> Self {
74 match self {
75 Self::EmptyModuleName => Self::EmptyModuleName,
76 Self::InvalidRoutePath(message) => Self::InvalidRoutePath(message.clone()),
77 Self::DuplicateRoute(message) => Self::DuplicateRoute(message.clone()),
78 Self::NotFound(message) => Self::NotFound(message.clone()),
79 Self::MethodNotAllowed(message) => Self::MethodNotAllowed(message.clone()),
80 Self::DuplicateProvider(message) => Self::DuplicateProvider(message.clone()),
81 Self::MissingProvider(message) => Self::MissingProvider(message.clone()),
82 Self::ProviderTypeMismatch(message) => Self::ProviderTypeMismatch(message.clone()),
83 Self::Forbidden(message) => Self::Forbidden(message.clone()),
84 Self::Unauthorized(message) => Self::Unauthorized(message.clone()),
85 Self::BadRequest(message) => Self::BadRequest(message.clone()),
86 Self::PayloadTooLarge(message) => Self::PayloadTooLarge(message.clone()),
87 Self::UnsupportedMediaType(message) => Self::UnsupportedMediaType(message.clone()),
88 Self::NotAcceptable(message) => Self::NotAcceptable(message.clone()),
89 Self::Adapter(message) => Self::Adapter(message.clone()),
90 Self::Internal(message) => Self::Internal(message.clone()),
91 Self::Io(error) => Self::Io(std::io::Error::new(error.kind(), error.to_string())),
92 }
93 }
94}