forked from
smokesignal.events/smokesignal
i18n+filtering fork - fluent-templates v2
1//! # Web Error Types
2//!
3//! This module defines the top-level error type for the HTTP layer that aggregates
4//! all domain-specific errors in the application. This allows errors to be handled
5//! uniformly at the HTTP boundary and converted into appropriate HTTP responses.
6//!
7//! Specific error variants use their own error codes, while general errors use the
8//! format: `error-web-<number> <message>: <details>`
9
10use axum::http::StatusCode;
11use axum::response::IntoResponse;
12use axum::response::Response;
13use thiserror::Error;
14
15use super::admin_errors::AdminImportEventError;
16use super::admin_errors::AdminImportRsvpError;
17use super::common_error::CommonError;
18use super::create_event_errors::CreateEventError;
19use super::edit_event_error::EditEventError;
20use super::event_view_errors::EventViewError;
21use super::import_error::ImportError;
22use super::login_error::LoginError;
23use super::middleware_errors::MiddlewareAuthError;
24use super::migrate_event_error::MigrateEventError;
25use super::migrate_rsvp_error::MigrateRsvpError;
26use super::rsvp_error::RSVPError;
27use super::url_error::UrlError;
28
29/// Represents all possible errors that can occur in the HTTP layer.
30///
31/// This enum serves as an aggregation point for all domain-specific errors
32/// in the application, allowing them to be handled uniformly at the HTTP boundary.
33///
34/// Most variants use transparent error forwarding to preserve the original error message
35/// and error code, while a few web-specific errors have their own error code format:
36/// `error-web-<number> <message>: <details>`
37#[derive(Debug, Error)]
38pub enum WebError {
39 /// Error when authentication middleware fails.
40 ///
41 /// This error occurs when there are issues with verifying a user's identity
42 /// through the authentication middleware, such as invalid credentials or
43 /// expired sessions.
44 ///
45 /// **Error Code:** `error-web-1`
46 #[error("error-web-1 Middleware Auth Error: {0:?}")]
47 MiddlewareAuthError(#[from] MiddlewareAuthError),
48
49 /// Error when an unexpected error occurs that isn't covered by other error types.
50 ///
51 /// This error is a fallback for any unhandled errors in the system. In production,
52 /// these should be rare as most errors should be properly typed.
53 ///
54 /// **Error Code:** `error-web-2`
55 ///
56 /// Note: This should be replaced with more specific error types as part of
57 /// the ongoing effort to use typed errors throughout the codebase.
58 #[error("error-web-2 Unhandled web error: {0:?}")]
59 Anyhow(#[from] anyhow::Error),
60
61 /// Common HTTP errors.
62 ///
63 /// This variant wraps errors from the common error module, which contains
64 /// frequently used error types shared across HTTP handlers.
65 #[error(transparent)]
66 Common(#[from] CommonError),
67
68 /// Login-related errors.
69 ///
70 /// This error occurs during login operations, such as invalid credentials,
71 /// account lockouts, or missing account information.
72 #[error(transparent)]
73 Login(#[from] LoginError),
74
75 /// Event editing errors.
76 ///
77 /// This error occurs when there are issues editing an event, such as
78 /// permission problems or invalid event data.
79 #[error(transparent)]
80 EditEvent(#[from] EditEventError),
81
82 /// Event migration errors.
83 ///
84 /// This error occurs when there are issues migrating events between
85 /// different formats or systems.
86 #[error(transparent)]
87 MigrateEvent(#[from] MigrateEventError),
88
89 /// RSVP migration errors.
90 ///
91 /// This error occurs when there are issues migrating RSVPs between
92 /// different formats or systems.
93 #[error(transparent)]
94 MigrateRsvp(#[from] MigrateRsvpError),
95
96 /// Admin RSVP import errors.
97 ///
98 /// This error occurs when administrators have issues importing RSVP
99 /// records into the system.
100 #[error(transparent)]
101 AdminImportRsvp(#[from] AdminImportRsvpError),
102
103 /// Admin event import errors.
104 ///
105 /// This error occurs when administrators have issues importing event
106 /// records into the system.
107 #[error(transparent)]
108 AdminImportEvent(#[from] AdminImportEventError),
109
110 /// RSVP-related errors.
111 ///
112 /// This error occurs during RSVP operations such as creation, updating,
113 /// or retrieval of RSVPs.
114 #[error(transparent)]
115 RSVP(#[from] RSVPError),
116
117 /// Cache operation errors.
118 ///
119 /// This error occurs when there are issues with cache operations such as
120 /// connection failures or data invalidation problems.
121 #[error(transparent)]
122 Cache(#[from] crate::storage::errors::CacheError),
123
124 /// JSON Web Key errors.
125 ///
126 /// This error occurs when there are issues with cryptographic keys,
127 /// such as missing or invalid keys.
128 #[error(transparent)]
129 JwkError(#[from] crate::jose_errors::JwkError),
130
131 /// JSON Object Signing and Encryption errors.
132 ///
133 /// This error occurs when there are issues with JWT operations,
134 /// such as signature validation or token creation.
135 #[error(transparent)]
136 JoseError(#[from] crate::jose_errors::JoseError),
137
138 /// Configuration errors.
139 ///
140 /// This error occurs when there are issues with application configuration,
141 /// such as missing environment variables or invalid settings.
142 #[error(transparent)]
143 ConfigError(#[from] crate::config_errors::ConfigError),
144
145 /// Data encoding/decoding errors.
146 ///
147 /// This error occurs when there are issues with data encoding or decoding,
148 /// such as invalid Base64 or JSON parsing problems.
149 #[error(transparent)]
150 EncodingError(#[from] crate::encoding_errors::EncodingError),
151
152 /// AT Protocol URI errors.
153 ///
154 /// This error occurs when there are issues with AT Protocol URIs,
155 /// such as malformed DIDs or invalid handles.
156 #[error(transparent)]
157 UriError(#[from] crate::atproto::errors::UriError),
158
159 /// Database storage errors.
160 ///
161 /// This error occurs when there are issues with database operations,
162 /// such as query failures or transaction issues.
163 #[error(transparent)]
164 StorageError(#[from] crate::storage::errors::StorageError),
165
166 /// Event view errors.
167 ///
168 /// This error occurs when there are issues with retrieving or
169 /// displaying events, such as invalid parameters or missing data.
170 #[error(transparent)]
171 EventViewError(#[from] EventViewError),
172
173 /// Event creation errors.
174 ///
175 /// This error occurs when there are issues with creating events,
176 /// such as validation failures or missing required fields.
177 #[error(transparent)]
178 CreateEventError(#[from] CreateEventError),
179
180 /// Event viewing errors.
181 ///
182 /// This error occurs when there are issues with viewing specific events,
183 /// such as permission problems or invalid event identifiers.
184 #[error(transparent)]
185 ViewEventError(#[from] super::view_event_error::ViewEventError),
186
187 /// Token refresh errors.
188 ///
189 /// This error occurs when there are issues with refreshing authentication
190 /// tokens, such as expired refresh tokens or validation failures.
191 #[error(transparent)]
192 RefreshError(#[from] crate::refresh_tokens_errors::RefreshError),
193
194 /// URL processing errors.
195 ///
196 /// This error occurs when there are issues with URL processing or validation,
197 /// such as malformed URLs or invalid parameters.
198 #[error(transparent)]
199 UrlError(#[from] UrlError),
200
201 /// Import-related errors.
202 ///
203 /// This error occurs when there are issues with importing data into the system,
204 /// such as format incompatibilities or validation failures.
205 #[error(transparent)]
206 ImportError(#[from] ImportError),
207}
208
209/// Implementation of Axum's `IntoResponse` trait for WebError.
210///
211/// This implementation converts errors into appropriate HTTP responses:
212/// - Authentication errors use their specialized response handling
213/// - All other errors are converted to a generic 500 Internal Server Error
214/// and logged with the `tracing` system.
215impl IntoResponse for WebError {
216 fn into_response(self) -> Response {
217 match self {
218 WebError::MiddlewareAuthError(err) => err.into_response(),
219 _ => {
220 tracing::error!(error = ?self, "internal server error");
221 (StatusCode::INTERNAL_SERVER_ERROR).into_response()
222 }
223 }
224 }
225}