axum_jwt_sessions/
error.rs1use axum::{
2 http::StatusCode,
3 response::{IntoResponse, Response},
4};
5use serde::Serialize;
6use thiserror::Error;
7
8#[derive(Debug, Serialize)]
10#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
11pub struct ErrorResponse {
12 pub error: &'static str,
14 pub message: &'static str,
16}
17
18#[derive(Error, Debug)]
19pub enum AuthError {
20 #[error("Invalid token")]
21 InvalidToken,
22
23 #[error("Token expired")]
24 TokenExpired,
25
26 #[error("Missing authorization header")]
27 MissingAuthHeader,
28
29 #[error("Invalid authorization header format")]
30 InvalidAuthHeaderFormat,
31
32 #[error("Session not found")]
33 SessionNotFound,
34
35 #[error("Storage error: {0}")]
36 StorageError(String),
37
38 #[error("Token generation failed: {0}")]
39 TokenGenerationError(String),
40
41 #[error("Invalid refresh token")]
42 InvalidRefreshToken,
43
44 #[error("Refresh token required")]
45 RefreshTokenRequired,
46}
47
48impl IntoResponse for AuthError {
49 fn into_response(self) -> Response {
50 let (status, message) = match self {
51 AuthError::InvalidToken => (StatusCode::UNAUTHORIZED, "Invalid token"),
52 AuthError::TokenExpired => (StatusCode::UNAUTHORIZED, "Token expired"),
53 AuthError::MissingAuthHeader => {
54 (StatusCode::UNAUTHORIZED, "Missing authorization header")
55 }
56 AuthError::InvalidAuthHeaderFormat => (
57 StatusCode::BAD_REQUEST,
58 "Invalid authorization header format",
59 ),
60 AuthError::SessionNotFound => (StatusCode::UNAUTHORIZED, "Session not found"),
61 AuthError::StorageError(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Storage error"),
62 AuthError::TokenGenerationError(_) => {
63 (StatusCode::INTERNAL_SERVER_ERROR, "Token generation failed")
64 }
65 AuthError::InvalidRefreshToken => (StatusCode::UNAUTHORIZED, "Invalid refresh token"),
66 AuthError::RefreshTokenRequired => (
67 StatusCode::FORBIDDEN,
68 "Refresh token required for this endpoint",
69 ),
70 };
71
72 let error_response = ErrorResponse {
73 error: match self {
74 AuthError::InvalidToken => "invalid_token",
75 AuthError::TokenExpired => "token_expired",
76 AuthError::MissingAuthHeader => "missing_authorization_header",
77 AuthError::InvalidAuthHeaderFormat => "invalid_authorization_header",
78 AuthError::SessionNotFound => "session_not_found",
79 AuthError::StorageError(_) => "storage_error",
80 AuthError::TokenGenerationError(_) => "token_generation_error",
81 AuthError::InvalidRefreshToken => "invalid_refresh_token",
82 AuthError::RefreshTokenRequired => "refresh_token_required",
83 },
84 message,
85 };
86
87 (status, axum::Json(error_response)).into_response()
88 }
89}
90
91pub type Result<T> = std::result::Result<T, AuthError>;