A decentralized event management and credentialing system built on atproto.
at main 83 lines 2.8 kB view raw
1use axum::http::StatusCode; 2use axum::response::IntoResponse; 3use axum::response::Response; 4 5use crate::errors::{AcudoError, EventError, HttpError}; 6 7/// Web layer error wrapper for HTTP responses. 8/// 9/// This type wraps the standardized HttpError and provides HTTP response conversion. 10/// All errors follow the format: `error-acudo-http-<number> <message>: <details>` 11#[derive(Debug)] 12pub(super) enum WebError { 13 /// HTTP layer error with proper error formatting 14 Http(HttpError), 15 16 /// Fallback for legacy anyhow errors during transition 17 Legacy(anyhow::Error), 18} 19 20impl From<HttpError> for WebError { 21 fn from(err: HttpError) -> Self { 22 WebError::Http(err) 23 } 24} 25 26impl From<AcudoError> for WebError { 27 fn from(err: AcudoError) -> Self { 28 match err { 29 AcudoError::Http(http_err) => WebError::Http(http_err), 30 other => WebError::Legacy(anyhow::Error::from(other)), 31 } 32 } 33} 34 35impl From<EventError> for WebError { 36 fn from(err: EventError) -> Self { 37 WebError::Legacy(anyhow::Error::from(err)) 38 } 39} 40 41impl From<anyhow::Error> for WebError { 42 fn from(err: anyhow::Error) -> Self { 43 WebError::Legacy(err) 44 } 45} 46 47/// Implementation of Axum's `IntoResponse` trait for WebError. 48/// 49/// This implementation converts errors into appropriate HTTP responses: 50/// - Authentication errors return 401 Unauthorized 51/// - Forbidden errors return 403 Forbidden 52/// - Not found errors return 404 Not Found 53/// - Validation errors return 400 Bad Request 54/// - All other errors return 500 Internal Server Error 55impl IntoResponse for WebError { 56 fn into_response(self) -> Response { 57 let (status, error_message) = match &self { 58 WebError::Http(http_err) => match http_err { 59 HttpError::AuthenticationRequired => { 60 (StatusCode::UNAUTHORIZED, http_err.to_string()) 61 } 62 HttpError::Forbidden => (StatusCode::FORBIDDEN, http_err.to_string()), 63 HttpError::NotFound => (StatusCode::NOT_FOUND, http_err.to_string()), 64 HttpError::RequestValidation { .. } => { 65 (StatusCode::BAD_REQUEST, http_err.to_string()) 66 } 67 HttpError::Unhandled { .. } => { 68 (StatusCode::INTERNAL_SERVER_ERROR, http_err.to_string()) 69 } 70 }, 71 WebError::Legacy(err) => ( 72 StatusCode::INTERNAL_SERVER_ERROR, 73 format!("error-acudo-http-100 Unhandled web error: {}", err), 74 ), 75 }; 76 77 tracing::error!(error = ?self, status = ?status, "HTTP error response"); 78 79 // Return simple error response for now 80 // In production, you might want to return JSON or a proper error page 81 (status, error_message).into_response() 82 } 83}