From 8e52c5246fbd2804294516b466a8fa60bbcf8aeb Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sun, 18 Sep 2022 21:32:47 +0200 Subject: [PATCH] Use `400 Bad Request` for `FailedToDeserializeQueryString` rejections (#1387) * Use `400 Bad Request` for `FailedToDeserializeQueryString` rejections Fixes https://github.com/tokio-rs/axum/issues/1378 From [the spec] about `422 Unprocessable Entity`: > For example, this error condition may occur if an XML request body > contains well-formed (i.e., syntactically correct), but semantically > erroneous, XML instructions. I understand this to mean that query params shouldn't use 422 because that is about the request body. So this changes `FailedToDeserializeQueryString` from `422 Unprocessable Entity` to `400 Bad Request`. [the spec]: https://datatracker.ietf.org/doc/html/rfc4918#section-11.2 * changelog --- axum/CHANGELOG.md | 3 +++ axum/src/extract/query.rs | 21 ++++++++++++++++++++- axum/src/extract/rejection.rs | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index ceb6f404..e0379c2d 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -12,8 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `serde_json::Error` ([#1371]) - **added**: `JsonRejection` now displays the path at which a deserialization error occurred too ([#1371]) +- **fixed:** Used `400 Bad Request` for `FailedToDeserializeQueryString` + rejections, instead of `422 Unprocessable Entity` ([#1387]) [#1371]: https://github.com/tokio-rs/axum/pull/1371 +[#1387]: https://github.com/tokio-rs/axum/pull/1387 # 0.6.0-rc.2 (10. September, 2022) diff --git a/axum/src/extract/query.rs b/axum/src/extract/query.rs index b4c34f94..a520853a 100644 --- a/axum/src/extract/query.rs +++ b/axum/src/extract/query.rs @@ -75,9 +75,11 @@ impl Deref for Query { #[cfg(test)] mod tests { + use crate::{routing::get, test_helpers::TestClient, Router}; + use super::*; use axum_core::extract::FromRequest; - use http::Request; + use http::{Request, StatusCode}; use serde::Deserialize; use std::fmt::Debug; @@ -124,4 +126,21 @@ mod tests { ) .await; } + + #[tokio::test] + async fn correct_rejection_status_code() { + #[derive(Deserialize)] + #[allow(dead_code)] + struct Params { + n: i32, + } + + async fn handler(_: Query) {} + + let app = Router::new().route("/", get(handler)); + let client = TestClient::new(app); + + let res = client.get("/?n=hi").send().await; + assert_eq!(res.status(), StatusCode::BAD_REQUEST); + } } diff --git a/axum/src/extract/rejection.rs b/axum/src/extract/rejection.rs index 135ad0a2..d6f11c31 100644 --- a/axum/src/extract/rejection.rs +++ b/axum/src/extract/rejection.rs @@ -116,7 +116,7 @@ impl FailedToDeserializeQueryString { impl IntoResponse for FailedToDeserializeQueryString { fn into_response(self) -> Response { - (http::StatusCode::UNPROCESSABLE_ENTITY, self.to_string()).into_response() + (http::StatusCode::BAD_REQUEST, self.to_string()).into_response() } }