Gnosco is a Rust-based escrow and badging application that integrates with the AT Protocol ecosystem..
1//! HTTP-specific error types and response handling.
2//!
3//! Error types for login failures, OAuth issues, and web request processing.
4//! Includes conversion to appropriate HTTP status codes and responses.
5
6use axum::http::StatusCode;
7use axum::response::IntoResponse;
8use axum::response::Response;
9use thiserror::Error;
10
11/// Represents errors that can occur during user login and authentication.
12///
13/// These errors typically happen during the authentication process when users
14/// are logging in to the application, including OAuth flows and DID validation.
15#[derive(Debug, Error)]
16pub(super) enum LoginError {
17 /// Error when a DID document does not contain a handle.
18 ///
19 /// This error occurs during authentication when the user's DID document
20 /// is retrieved but does not contain a required handle identifier.
21 #[error("error-login-1 DID document does not contain a handle")]
22 NoHandle,
23
24 /// Error when a DID document does not contain a PDS endpoint.
25 ///
26 /// This error occurs during authentication when the user's DID document
27 /// is retrieved but does not contain a required AT Protocol Personal
28 /// Data Server (PDS) endpoint.
29 #[error("error-login-2 DID document does not contain an AT Protocol PDS endpoint")]
30 NoPDS,
31
32 /// Error when an OAuth callback is incomplete.
33 ///
34 /// This error occurs when the OAuth authentication flow callback
35 /// returns with incomplete information, preventing successful authentication.
36 #[error("error-login-3 OAuth callback incomplete")]
37 OAuthCallbackIncomplete,
38
39 /// Error when there is an OAuth issuer mismatch.
40 ///
41 /// This error occurs when the issuer in the OAuth response does not
42 /// match the expected issuer, which could indicate a security issue.
43 #[error("error-login-4 OAuth issuer mismatch")]
44 OAuthIssuerMismatch,
45}
46
47/// Represents all possible errors that can occur in the HTTP layer.
48///
49/// This enum serves as an aggregation point for all domain-specific errors
50/// in the application, allowing them to be handled uniformly at the HTTP boundary.
51///
52/// Most variants use transparent error forwarding to preserve the original error message
53/// and error code, while a few web-specific errors have their own error code format:
54/// `error-web-<number> <message>: <details>`
55#[derive(Debug, Error)]
56pub(super) enum WebError {
57 /// Error when an unexpected error occurs that isn't covered by other error types.
58 ///
59 /// This error is a fallback for any unhandled errors in the system. In production,
60 /// these should be rare as most errors should be properly typed.
61 #[error("error-web-1 Unhandled web error: {0:?}")]
62 Anyhow(#[from] anyhow::Error),
63}
64
65/// Implementation of Axum's `IntoResponse` trait for WebError.
66///
67/// This implementation converts errors into appropriate HTTP responses:
68/// - Authentication errors use their specialized response handling
69/// - All other errors are converted to a generic 500 Internal Server Error
70/// and logged with the `tracing` system.
71impl IntoResponse for WebError {
72 fn into_response(self) -> Response {
73 {
74 tracing::error!(error = ?self, "internal server error");
75 (StatusCode::INTERNAL_SERVER_ERROR).into_response()
76 }
77 }
78}