axum_oidc_client/
errors.rs1use axum::response::IntoResponse;
2
3#[cfg(feature = "redis")]
4use redis::RedisError;
5
6#[derive(Debug)]
7pub enum Error {
8 MissingCodeVerifier,
9 MissingPatameter(String),
10 NotValidUri(String),
11 Request(reqwest::Error),
12 InvalidCodeResponse(serde_html_form::de::Error),
13 InvalidTokenResponse(serde_json::Error),
14 InvalidResponse(String),
15 CacheError(String),
16 TokenRefreshFailed(String),
17 BadRequest(String),
19 Unauthorized(String),
20 Forbidden(String),
21 NotFound(String),
22 TooManyRequests(String),
23 InternalServerError(String),
24 BadGateway(String),
25 ServiceUnavailable(String),
26 UnknownStatusCode(u16, String),
27 AuthCacheNotConfigured,
29 OAuthConfigNotConfigured,
30 HttpClientNotConfigured,
31 SessionNotFound,
33 SessionExpired,
34 CacheAccessError(String),
35 SessionUpdateFailed(String),
36 TokenRefreshFailedAuth(String),
37}
38
39impl IntoResponse for Error {
40 fn into_response(self) -> axum::response::Response {
41 match self {
42 Error::InvalidResponse(res) => {
43 let message = format!("Invalid response {res}");
44 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
45 }
46
47 Error::MissingCodeVerifier => {
48 let message = "Missing code verifier";
49 (axum::http::StatusCode::BAD_REQUEST, message).into_response()
50 }
51 Error::MissingPatameter(param) => {
52 let message = format!("Missing parameter: {param}");
53 (axum::http::StatusCode::BAD_REQUEST, message).into_response()
54 }
55 Error::NotValidUri(uri) => {
56 let message = format!("Not a valid URI: {uri}");
57 (axum::http::StatusCode::BAD_REQUEST, message).into_response()
58 }
59 Error::Request(err) => {
60 let message = format!("Reqwest error: {err}");
61 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
62 }
63 Error::InvalidCodeResponse(err) => {
64 let message = format!("Invalid code response: {err}");
65 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
66 }
67 Error::InvalidTokenResponse(err) => {
68 let message = format!("Invalid token response: {err}");
69 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
70 }
71 Error::CacheError(err) => {
72 let message = format!("Cache error: {err}");
73 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
74 }
75 Error::TokenRefreshFailed(err) => {
76 let message = format!("Token refresh failed: {err}");
77 (axum::http::StatusCode::UNAUTHORIZED, message).into_response()
78 }
79 Error::BadRequest(msg) => (axum::http::StatusCode::BAD_REQUEST, msg).into_response(),
81 Error::Unauthorized(msg) => (axum::http::StatusCode::UNAUTHORIZED, msg).into_response(),
82 Error::Forbidden(msg) => (axum::http::StatusCode::FORBIDDEN, msg).into_response(),
83 Error::NotFound(msg) => (axum::http::StatusCode::NOT_FOUND, msg).into_response(),
84 Error::TooManyRequests(msg) => {
85 (axum::http::StatusCode::TOO_MANY_REQUESTS, msg).into_response()
86 }
87 Error::InternalServerError(msg) => {
88 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, msg).into_response()
89 }
90 Error::BadGateway(msg) => (axum::http::StatusCode::BAD_GATEWAY, msg).into_response(),
91 Error::ServiceUnavailable(msg) => {
92 (axum::http::StatusCode::SERVICE_UNAVAILABLE, msg).into_response()
93 }
94 Error::UnknownStatusCode(code, msg) => {
95 let message = format!("HTTP {code}: {msg}");
96 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
97 }
98 Error::AuthCacheNotConfigured => {
100 let message = "AuthCache not configured. Make sure to add it to your app with Extension(cache).";
101 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
102 }
103 Error::OAuthConfigNotConfigured => {
104 let message = "OAuthConfiguration not configured. Make sure to add it to your app with Extension(config).";
105 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
106 }
107 Error::HttpClientNotConfigured => {
108 let message = "HTTP Client not configured. Make sure to use AuthLayer middleware.";
109 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
110 }
111 Error::SessionNotFound => {
113 let message = "No active session found. Please log in.";
114 (axum::http::StatusCode::UNAUTHORIZED, message).into_response()
115 }
116 Error::SessionExpired => {
117 let message = "Session expired or not found. Please log in again.";
118 (axum::http::StatusCode::UNAUTHORIZED, message).into_response()
119 }
120 Error::CacheAccessError(msg) => {
121 let message = format!("Cache error: {msg}");
122 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
123 }
124 Error::SessionUpdateFailed(msg) => {
125 let message = format!("Failed to update session in cache: {msg}");
126 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
127 }
128 Error::TokenRefreshFailedAuth(msg) => {
129 let message =
130 format!("Token expired and refresh failed. Please log in again: {msg}");
131 (axum::http::StatusCode::UNAUTHORIZED, message).into_response()
132 }
133 }
134 }
135}
136
137impl Error {
138 pub fn from_status_code(status: axum::http::StatusCode, response_text: String) -> Self {
140 match status {
141 axum::http::StatusCode::BAD_REQUEST => Error::BadRequest(response_text),
142 axum::http::StatusCode::UNAUTHORIZED => Error::Unauthorized(response_text),
143 axum::http::StatusCode::FORBIDDEN => Error::Forbidden(response_text),
144 axum::http::StatusCode::NOT_FOUND => Error::NotFound(response_text),
145 axum::http::StatusCode::TOO_MANY_REQUESTS => Error::TooManyRequests(response_text),
146 axum::http::StatusCode::INTERNAL_SERVER_ERROR => {
147 Error::InternalServerError(response_text)
148 }
149 axum::http::StatusCode::BAD_GATEWAY => Error::BadGateway(response_text),
150 axum::http::StatusCode::SERVICE_UNAVAILABLE => Error::ServiceUnavailable(response_text),
151 _ => Error::UnknownStatusCode(status.as_u16(), response_text),
152 }
153 }
154}
155
156impl From<reqwest::Error> for Error {
157 fn from(err: reqwest::Error) -> Self {
158 Error::Request(err)
159 }
160}
161
162impl From<serde_json::Error> for Error {
163 fn from(err: serde_json::Error) -> Self {
164 Error::InvalidTokenResponse(err)
165 }
166}
167
168impl From<serde_html_form::de::Error> for Error {
169 fn from(err: serde_html_form::de::Error) -> Self {
170 Error::InvalidCodeResponse(err)
171 }
172}
173
174#[cfg(feature = "redis")]
175impl From<RedisError> for Error {
176 fn from(err: RedisError) -> Self {
177 Error::CacheError(err.to_string())
178 }
179}