auth0_jwt/
error.rs

1#[cfg(feature = "axum")]
2use axum::{extract::rejection::TypedHeaderRejection, response::IntoResponse, Json};
3
4use reqwest::StatusCode;
5use serde::Serialize;
6use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug, Error)]
11pub enum Error {
12    #[error("Failed to fetch JWKS")]
13    JWKSFetchError,
14
15    #[error("Reqwest error: {0}")]
16    ReqwestError(#[from] reqwest::Error),
17
18    #[error("Failed to decode token kid")]
19    TokenKidDecodeError,
20
21    #[error("{0}")]
22    ValidationError(alcoholic_jwt::ValidationError),
23
24    #[error("Failed to deserialize json: {0}")]
25    DeserializationError(serde_json::Error),
26
27    #[cfg(feature = "axum")]
28    #[error("Invalid authorization header")]
29    InvalidTokenHeader(TypedHeaderRejection),
30}
31
32impl Error {
33    pub fn status_code(&self) -> StatusCode {
34        match self {
35            Self::DeserializationError(_)
36            | Self::TokenKidDecodeError
37            | Self::ValidationError(_)
38            | Self::JWKSFetchError => StatusCode::FORBIDDEN,
39            _ => StatusCode::UNAUTHORIZED,
40        }
41    }
42
43    pub fn title(&self) -> &'static str {
44        match self {
45            Self::DeserializationError(_) => "Deserialization Error",
46            Self::TokenKidDecodeError => "Invalid token kid",
47            Self::ValidationError(_) => "Invalid Token",
48            Self::JWKSFetchError => "JWKS fetch error",
49            _ => "Internal Server Error",
50        }
51    }
52}
53
54#[cfg(feature = "axum")]
55impl IntoResponse for Error {
56    fn into_response(self) -> axum::response::Response {
57        (self.status_code(), Json(ErrorBody::from_error(self))).into_response()
58    }
59}
60
61#[derive(Debug, Serialize)]
62pub struct ErrorBody {
63    pub title: String,
64    pub message: String,
65    pub status_code: u16,
66}
67
68impl ErrorBody {
69    pub fn from_error(error: Error) -> Self {
70        Self {
71            title: error.title().to_string(),
72            message: error.to_string(),
73            status_code: error.status_code().as_u16(),
74        }
75    }
76}