rustack_apigatewayv2_model/
error.rs1use std::fmt;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
10#[non_exhaustive]
11pub enum ApiGatewayV2ErrorCode {
12 #[default]
14 AccessDeniedException,
15 BadRequestException,
17 ConflictException,
19 NotFoundException,
21 TooManyRequestsException,
23 UnknownOperation,
25}
26
27impl ApiGatewayV2ErrorCode {
28 #[must_use]
30 pub fn error_type(&self) -> &'static str {
31 self.as_str()
32 }
33
34 #[must_use]
36 pub fn as_str(&self) -> &'static str {
37 match self {
38 Self::AccessDeniedException => "AccessDeniedException",
39 Self::BadRequestException => "BadRequestException",
40 Self::ConflictException => "ConflictException",
41 Self::NotFoundException => "NotFoundException",
42 Self::TooManyRequestsException => "TooManyRequestsException",
43 Self::UnknownOperation => "UnknownOperation",
44 }
45 }
46
47 #[must_use]
49 pub fn default_status_code(&self) -> http::StatusCode {
50 match self {
51 Self::BadRequestException => http::StatusCode::BAD_REQUEST,
52 Self::AccessDeniedException => http::StatusCode::FORBIDDEN,
53 Self::NotFoundException => http::StatusCode::NOT_FOUND,
54 Self::ConflictException => http::StatusCode::CONFLICT,
55 Self::TooManyRequestsException | Self::UnknownOperation => {
56 http::StatusCode::INTERNAL_SERVER_ERROR
57 }
58 }
59 }
60}
61
62impl fmt::Display for ApiGatewayV2ErrorCode {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.write_str(self.as_str())
65 }
66}
67
68#[derive(Debug)]
70pub struct ApiGatewayV2Error {
71 pub code: ApiGatewayV2ErrorCode,
73 pub message: String,
75 pub status_code: http::StatusCode,
77 pub source: Option<Box<dyn std::error::Error + Send + Sync>>,
79}
80
81impl fmt::Display for ApiGatewayV2Error {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "ApiGatewayV2Error({}): {}", self.code, self.message)
84 }
85}
86
87impl std::error::Error for ApiGatewayV2Error {
88 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
89 self.source
90 .as_ref()
91 .map(|e| e.as_ref() as &(dyn std::error::Error + 'static))
92 }
93}
94
95impl ApiGatewayV2Error {
96 #[must_use]
98 pub fn new(code: ApiGatewayV2ErrorCode) -> Self {
99 Self {
100 status_code: code.default_status_code(),
101 message: code.as_str().to_owned(),
102 code,
103 source: None,
104 }
105 }
106
107 #[must_use]
109 pub fn with_message(code: ApiGatewayV2ErrorCode, message: impl Into<String>) -> Self {
110 Self {
111 status_code: code.default_status_code(),
112 message: message.into(),
113 code,
114 source: None,
115 }
116 }
117
118 #[must_use]
120 pub fn error_type(&self) -> &'static str {
121 self.code.error_type()
122 }
123
124 #[must_use]
126 pub fn internal_error(message: impl Into<String>) -> Self {
127 Self::with_message(ApiGatewayV2ErrorCode::UnknownOperation, message)
128 }
129
130 #[must_use]
132 pub fn unknown_operation(method: &http::Method, path: &str) -> Self {
133 Self::with_message(
134 ApiGatewayV2ErrorCode::UnknownOperation,
135 format!("no ApiGatewayV2 operation matches {method} {path}"),
136 )
137 }
138
139 #[must_use]
141 pub fn not_implemented(operation: &str) -> Self {
142 Self::with_message(
143 ApiGatewayV2ErrorCode::UnknownOperation,
144 format!("Operation {operation} is not yet implemented"),
145 )
146 }
147}
148
149#[macro_export]
158macro_rules! apigatewayv2_error {
159 ($code:ident) => {
160 $crate::error::ApiGatewayV2Error::new($crate::error::ApiGatewayV2ErrorCode::$code)
161 };
162 ($code:ident, $msg:expr) => {
163 $crate::error::ApiGatewayV2Error::with_message(
164 $crate::error::ApiGatewayV2ErrorCode::$code,
165 $msg,
166 )
167 };
168}