Hi everyone!
I'm a very newbie on Rust and rocket. I wonder how handle JSON validation. I see the guard Json but how return a 4xx json response with serde error?
Thanks
You will want to post some more details and code of what you want for more detailed help, but let's say your return type on success is some type I will denote by S
. Then you can change the return type to e.g. Result<S, BadRequest<Json>>
to return either an Ok(successful_value_here)
or an Err(BadRequest(Json(object_to_convert_to_json)))
to show the error.
The BadRequest
part is a wrapper you can put around a response, which responds with the wrapped item and sets the response code to 400 Bad Request. If you wish to return multiple different response codes in different situations, you can use the Custom
wrapper instead, which allows you to pass the status code as an argument instead of letting it be part of the type.
The Json
thing in the type above is a wrapper around any object that will serialize the object to json and respond with it (and set the content type). When using this tool, serialization is done using the crate serde. Note that this is not the same as the content::Json
type, which is more like BadRequest
and just accepts a string and sets the content type, while the one from rocket_contrib
will also perform the conversion to json for you.
Note that all of this is for the situation where the json you received was valid json, but the values in the json is bad in some way.
Hi Alice!
Thanks for your answer.
I started with this code:
But I got an internal server error
Error: Response was a non-`Responder` `Err`: BadRequest(Some(Json(ErrorMessage { message: "invalid type: integer `1`, expected a string at line 1 column 11" })))
@j3ans please do not share code as images, but as plain text instead.
Stackoverflow has a neat entry about this.
There are quite a lot of types missing in your image such as Hello and MyError
Sorry for the picture. Here, the code:
#[derive(Debug, Serialize, Deserialize, Validate)]
struct Hello {
#[validate(length(min = 5, max = 20))]
name: String,
}
#[derive(Debug)]
enum MyError {
BadPayload(String)
}
#[derive(Debug, Deserialize)]
struct ErrorMessage {
message: String,
}
impl FromDataSimple for Hello {
type Error = MyError;
fn from_data(req: &Request, data: Data) -> data::Outcome<Self, MyError> {
let hello: serde_json::Result<Hello> = serde_json::from_reader(data.open());
match hello {
Ok(h) => data::Outcome::Success(h),
Err(e) => {
data::Outcome::Failure((Status::UnprocessableEntity, MyError::BadPayload(e.to_string())))
}
}
}
}
#[post("/hello", data = "<hello>")]
fn index(hello: Result<Hello, MyError>) -> Result<Json<Hello>, response::status::BadRequest<Json<ErrorMessage>>> {
match hello {
Ok(h) => Ok(Json(h)),
Err(error) => {
match error {
MyError::BadPayload(s) => Err(response::status::BadRequest(Some(Json(ErrorMessage {message: s.to_string() }))))
}
}
}
}
Ok so I found my mistake. Missing Serialize
derive on ErrorMessage
.
What was the error message?
The error message was : Error: Response was a non-Responder
How did it even compile in the first place if that was the mistake?
I don't know
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.