From 80124af8364468fe40a4146aee0d18b1a43a1c1c Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sat, 3 May 2025 09:48:53 -0400 Subject: [PATCH] Handle bad json. --- src/document.rs | 42 ++++++++++++++++++++++++++++++++++++++---- src/field.rs | 4 ++-- src/lib.rs | 3 ++- src/main.rs | 23 +++++++++++++++++++++++ 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/document.rs b/src/document.rs index 84c2b28..31f1fe2 100644 --- a/src/document.rs +++ b/src/document.rs @@ -58,10 +58,18 @@ impl Document { reply.add_data("error_type", ErrorType::DocumentAlreadyExists); self.queue.send(reply).unwrap(); return; - }, - None => {}, + } + None => {} } - let doc: Value = serde_json::from_str(&msg.get_data("doc").unwrap().to_string()).unwrap(); + let doc: Value = match serde_json::from_str(&msg.get_data("doc").unwrap().to_string()) { + Ok(value) => value, + Err(_) => { + let mut reply = msg.reply(MsgType::Error); + reply.add_data("error_type", ErrorType::DocumentInvalidRequest); + self.queue.send(reply).unwrap(); + return; + } + }; self.data .insert(name, doc["template"].as_str().unwrap().to_string()); self.queue.send(msg.reply(MsgType::ActionOk)).unwrap(); @@ -220,7 +228,7 @@ pub mod documents { let reply = rx.recv_timeout(TIMEOUT).unwrap(); assert_eq!(reply.get_id(), msg.get_id()); match reply.get_msg_type() { - MsgType::Error=> {}, + MsgType::Error => {} _ => unreachable!( "got '{:?}': should have received document", reply.get_msg_type() @@ -238,4 +246,30 @@ pub mod documents { let result = binding.get_data("doc").unwrap(); assert_eq!(result.to_string(), expected.to_string()); } + + #[test] + fn invalid_json() { + let (queue, rx) = setup_document(); + let mut msg = Message::new(MsgType::DocumentRequest); + msg.add_data("action", ActionType::Add); + msg.add_data("name", "doc"); + msg.add_data("doc", "Invalid json request."); + queue.send(msg.clone()).unwrap(); + let reply = rx.recv_timeout(TIMEOUT).unwrap(); + assert_eq!(reply.get_id(), msg.get_id()); + match reply.get_msg_type() { + MsgType::Error => {} + _ => unreachable!( + "got '{:?}': should have received document", + reply.get_msg_type() + ), + } + match reply.get_data("error_type") { + Some(err) => match err.to_error_type().unwrap() { + ErrorType::DocumentInvalidRequest => {} + _ => unreachable!("got {:?}: should have been bad request'", err), + }, + None => unreachable!("should contain error type"), + } + } } diff --git a/src/field.rs b/src/field.rs index d991781..526f7e8 100644 --- a/src/field.rs +++ b/src/field.rs @@ -233,7 +233,7 @@ mod fields { let field: Field = err.into(); match field { Field::ErrorType(data) => match data { - ErrorType::DocumentNotFound => {} + ErrorType::DocumentNotFound => {} _ => unreachable!("got {:?}: should have been Document not found", data), }, _ => unreachable!("should have been an error type"), @@ -252,7 +252,7 @@ mod fields { let field: Field = err.into(); let result = field.to_error_type().unwrap(); match result { - ErrorType::DocumentNotFound => {} + ErrorType::DocumentNotFound => {} _ => unreachable!("got {:?}: should have been document not found", result), } } diff --git a/src/lib.rs b/src/lib.rs index 590f1da..f9bd115 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ pub enum ActionType { #[derive(Clone, Debug)] pub enum ErrorType { DocumentAlreadyExists, + DocumentInvalidRequest, DocumentNotFound, } @@ -75,7 +76,7 @@ mod mtt_replies { let reply = MTTReply::new(msg); match reply.get_error() { Some(err) => match err { - ErrorType::DocumentNotFound => {}, + ErrorType::DocumentNotFound => {} _ => unreachable!("got {:?}: should have been document not found", err), }, None => unreachable!("should return an error type"), diff --git a/src/main.rs b/src/main.rs index e665e05..7c49987 100644 --- a/src/main.rs +++ b/src/main.rs @@ -106,7 +106,9 @@ async fn mtt_conn( let status = match reply.get_error() { Some(err) => match err { ErrorType::DocumentAlreadyExists => StatusCode::CONFLICT, + ErrorType::DocumentInvalidRequest => StatusCode::BAD_REQUEST, ErrorType::DocumentNotFound => StatusCode::NOT_FOUND, + // _ => StatusCode::INTERNAL_SERVER_ERROR, }, None => StatusCode::OK, }; @@ -261,4 +263,25 @@ mod servers { "do not allow post to existing documents" ); } + + #[tokio::test] + async fn invalid_json() { + let app = create_app(MoreThanText::new()).await; + let response = app + .clone() + .oneshot( + Request::builder() + .method(Method::POST) + .uri("/api/something") + .body("Some invalid json.".to_string()) + .unwrap(), + ) + .await + .unwrap(); + assert_eq!( + response.status(), + StatusCode::BAD_REQUEST, + "do not allow post to existing documents" + ); + } }