Convert the error messages to json

Hi
I am validating using the crate "validator",
It works fine, but I don't know how to convert the errors to json

#[derive(Debug, Validate, serde::Serialize, serde::Deserialize)]
struct UserData {
    #[validate(length(min = 2, max = 20))]
    name: String,
    #[validate(required)]
    allow_cookies: Option<bool>,
    #[validate(email)]
    mail: String 
}

let udata = UserData{
...
}

udata.validate()?;

The error it shows me in my API is this, which is not a valid json

{
  "data": null,
  "errors": [
    {
      "message": "ValidationErrors({\"last_name\": Field([ValidationError { code: \"length\", message: None, params: {\"min\": Number(1), \"max\": Number(10), \"value\": String(\"\")} }])})",
    
    }
  ]
}
 

Crates

serde = { version = "1.0.117", features = ["derive"] }
serde_json = "1.0"
validator = { version = "0.12", features = ["derive"] }

How can I convert the error messages to json?

What in your code is outputting the {"data": null, "errors": [...]} object? That seems to be treating the ValidationErrors as a string, but it needs to treat it as serde::Serialize.

1 Like

This return the all validations mesages, And I don't know how to pass it to Json format

udata.validate()?;

What is the return type of the function you call udata.validate()? in, though? I'm assuming it's a Result<_, ValidationErrors> so that you can use ?. Somewhere, that ValidationErrors is being put into the object your API is returning. Without seeing the way you're using that function's return value it's difficult to tell what's going wrong.

It'd help if you could post more of the code here - the full definition of the function calling udata.validate(), what function calls that, etc.

Here the validation is done and the API is launched

#[async_graphql::Object]
impl MutationRoot {
    //user
    async fn user_create(
        &self,
        ctx: &Context<'_>,
        input: UserInputType,
    ) -> FieldResult<UserReponseType> {
        let pool = ctx.data::<PgPool>()?;

        let udata = input.get_data();

udata.validate()?; //<- This validate and display messages

        let row = UserRepository::create(&pool, data).await?;
        let item = UserReponseType::new(row);

        Ok(item)
    }

Does the error type implement the Serialize trait? (There may be a serde feature that needs to be enabled)

I think what's happening is ? is converting the ValidationErrors into an async_graphql::Error using Display, which is why it's just displaying like you'd see in a standard debug. You'll have to intercept that and turn it into JSON yourself; try replacing

udata.validate()?;

with

udata
    .validate()
    .map_err(|e| serde_json::to_string(e).unwrap())?;

That will turn the error into a JSON string (it will panic if it couldn't turn it into JSON; if you don't want that, replace the unwrap with an unwrap_or_else provided with a function that turns a serde_json::Error into a String.

To note, this just embeds JSON in a string; it doesn't actually nest the error JSON. You'll get something like

{
  "data": null,
  "errors": [
    {
      "message": "{ \"last_name\": [{ \"code\": \"length\", \"message\": null }]}" // etc.
    }
  ]
}

As far as I can tell, there isn't a way to get async-graphql to let you properly nest JSON; you can only return a string.

1 Like

thank you! it worked!!!