Skip to content

Commit

Permalink
return 422 status code for JSON rejection errors (#1173)
Browse files Browse the repository at this point in the history
* return 422 status code for JSON rejection errors

* return 422 status code for JSON rejection errors
  • Loading branch information
kaplanelad authored Jan 12, 2025
1 parent 426fa1b commit 0c20eb3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ impl<T: Serialize> IntoResponse for Json<T> {

impl IntoResponse for Error {
/// Convert an `Error` into an HTTP response.
#[allow(clippy::cognitive_complexity)]
fn into_response(self) -> Response {
match &self {
Self::WithBacktrace {
Expand Down Expand Up @@ -221,6 +222,11 @@ impl IntoResponse for Error {
StatusCode::BAD_REQUEST,
ErrorDetail::new("Bad Request", &err),
),
Self::JsonRejection(err) => {
tracing::debug!(err = err.body_text(), "json rejection");
(err.status(), ErrorDetail::with_reason("Bad Request"))
}

_ => (
StatusCode::INTERNAL_SERVER_ERROR,
ErrorDetail::new("internal_server_error", "Internal Server Error"),
Expand Down
41 changes: 41 additions & 0 deletions tests/controller/into_response.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::infra_cfg;
use loco_rs::{controller, prelude::*, tests_cfg};
use serde::{Deserialize, Serialize};
use serial_test::serial;

#[tokio::test]
Expand Down Expand Up @@ -162,3 +163,43 @@ async fn custom_error() {

handle.abort();
}

#[tokio::test]
#[serial]
async fn json_rejection() {
let ctx = tests_cfg::app::get_app_context().await;

#[allow(clippy::items_after_statements)]
#[derive(Debug, Deserialize, Serialize)]
pub struct Data {
pub email: String,
}

#[allow(clippy::items_after_statements)]
async fn action(Json(_params): Json<Data>) -> Result<Response> {
format::json(())
}

let handle = infra_cfg::server::start_with_route(ctx, "/", post(action)).await;

let client = reqwest::Client::new();
let res = client
.post(infra_cfg::server::get_base_url())
.json(&serde_json::json!({}))
.send()
.await
.expect("Valid response");

assert_eq!(res.status(), 422);

let res_text = res.text().await.expect("response text");
let res_json: serde_json::Value = serde_json::from_str(&res_text).expect("Valid JSON response");

let expected_json = serde_json::json!({
"error": "Bad Request",
});

assert_eq!(res_json, expected_json);

handle.abort();
}

0 comments on commit 0c20eb3

Please sign in to comment.