1use axum::body::Body;
2use axum::http::{header, HeaderValue, Response, StatusCode};
3use rustauth::api::ApiErrorResponse;
4
5#[non_exhaustive]
7#[derive(Debug, thiserror::Error)]
8pub enum RustAuthAxumError {
9 #[error("RustAuth base path must be an absolute literal path mountable by Axum: {0}")]
10 InvalidBasePath(String),
11 #[error("RustAuth base_url is not a valid absolute URL: {0}")]
12 InvalidBaseUrl(String),
13 #[error(
14 "RustAuth base_url path `{url_path}` does not match configured base_path `{base_path}`"
15 )]
16 InconsistentBaseUrlPath { url_path: String, base_path: String },
17}
18
19pub(crate) fn bad_request_response() -> axum::response::Response {
20 json_error_response(
21 StatusCode::BAD_REQUEST,
22 "INVALID_REQUEST_BODY",
23 "Invalid request body",
24 None,
25 )
26}
27
28pub(crate) fn payload_too_large_response() -> axum::response::Response {
29 json_error_response(
30 StatusCode::PAYLOAD_TOO_LARGE,
31 "PAYLOAD_TOO_LARGE",
32 "Payload too large",
33 None,
34 )
35}
36
37pub(crate) fn internal_error_response() -> axum::response::Response {
38 json_error_response(
39 StatusCode::INTERNAL_SERVER_ERROR,
40 "INTERNAL_SERVER_ERROR",
41 "Internal server error",
42 None,
43 )
44}
45
46pub(crate) fn json_error_response(
47 status: StatusCode,
48 code: &str,
49 message: &str,
50 original_message: Option<String>,
51) -> axum::response::Response {
52 let body = serde_json::to_vec(&ApiErrorResponse {
53 code: code.to_owned(),
54 message: message.to_owned(),
55 original_message,
56 })
57 .unwrap_or_else(|_| {
58 b"{\"code\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Internal server error\"}".to_vec()
59 });
60 let mut response = Response::new(Body::from(body));
61 *response.status_mut() = status;
62 response.headers_mut().insert(
63 header::CONTENT_TYPE,
64 HeaderValue::from_static("application/json"),
65 );
66 response
67}