fix: Use error page for extractor rejections

This commit is contained in:
Ginger
2026-03-18 12:42:55 -04:00
parent eec7103910
commit 8c4844b00b
2 changed files with 23 additions and 5 deletions
+11 -1
View File
@@ -1,6 +1,7 @@
use askama::Template; use askama::Template;
use axum::{ use axum::{
Router, Router,
extract::rejection::{FormRejection, QueryRejection},
http::{HeaderValue, StatusCode, header}, http::{HeaderValue, StatusCode, header},
response::{Html, IntoResponse, Response}, response::{Html, IntoResponse, Response},
}; };
@@ -18,6 +19,12 @@ enum WebError {
Render(#[from] askama::Error), Render(#[from] askama::Error),
#[error("Failed to validate form body: {0}")] #[error("Failed to validate form body: {0}")]
ValidationError(#[from] validator::ValidationErrors), ValidationError(#[from] validator::ValidationErrors),
#[error("{0}")]
QueryRejection(#[from] QueryRejection),
#[error("{0}")]
FormRejection(#[from] FormRejection),
#[error("Bad request: {0}")] #[error("Bad request: {0}")]
BadRequest(String), BadRequest(String),
#[error("This page does not exist.")] #[error("This page does not exist.")]
@@ -35,7 +42,10 @@ impl IntoResponse for WebError {
status: StatusCode, status: StatusCode,
} }
let status = match &self { let status = match &self {
| Self::ValidationError(_) | Self::BadRequest(_) => StatusCode::BAD_REQUEST, | Self::ValidationError(_)
| Self::BadRequest(_)
| Self::QueryRejection(_)
| Self::FormRejection(_) => StatusCode::BAD_REQUEST,
| Self::NotFound => StatusCode::NOT_FOUND, | Self::NotFound => StatusCode::NOT_FOUND,
| _ => StatusCode::INTERNAL_SERVER_ERROR, | _ => StatusCode::INTERNAL_SERVER_ERROR,
}; };
+12 -4
View File
@@ -1,7 +1,10 @@
use askama::Template; use askama::Template;
use axum::{ use axum::{
Router, Router,
extract::{Query, State}, extract::{
Query, State,
rejection::{FormRejection, QueryRejection},
},
http::StatusCode, http::StatusCode,
response::{Html, IntoResponse, Response}, response::{Html, IntoResponse, Response},
routing::get, routing::get,
@@ -78,16 +81,21 @@ async fn password_reset_form(
async fn get_password_reset( async fn get_password_reset(
State(services): State<crate::State>, State(services): State<crate::State>,
Query(query): Query<PasswordResetQuery>, query: Result<Query<PasswordResetQuery>, QueryRejection>,
) -> Result<impl IntoResponse, WebError> { ) -> Result<impl IntoResponse, WebError> {
let Query(query) = query?;
password_reset_form(services, query, PasswordResetForm::build(None)).await password_reset_form(services, query, PasswordResetForm::build(None)).await
} }
async fn post_password_reset( async fn post_password_reset(
State(services): State<crate::State>, State(services): State<crate::State>,
Query(query): Query<PasswordResetQuery>, query: Result<Query<PasswordResetQuery>, QueryRejection>,
axum::Form(form): axum::Form<PasswordResetForm>, form: Result<axum::Form<PasswordResetForm>, FormRejection>,
) -> Result<Response, WebError> { ) -> Result<Response, WebError> {
let Query(query) = query?;
let axum::Form(form) = form?;
match form.validate() { match form.validate() {
| Ok(()) => { | Ok(()) => {
let Some(token) = services.password_reset.check_token(&query.token).await else { let Some(token) = services.password_reset.check_token(&query.token).await else {