rambler-digital-solutions / actix-web-validator

Rust library for providing validation mechanism to actix-web with Validator crate.
MIT License
101 stars 26 forks source link

Nested Validation Error Output #28

Closed JohnSchneider closed 2 years ago

JohnSchneider commented 3 years ago

I have Actix-Web web services properly responding with HTTP 400 codes and descriptive error message when validation fails for simple use cases. However, when using nested validation (struct with derived Validate containing another struct with derived Validate), the error message returned by Actix-Web-Validator is not very descriptive.

Please consider the following stucts:

#[derive(Serialize, Deserialize, Validate, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SearchParams {
    #[validate]
    page_params: PageParams,
    determine_total_count: bool
}

#[derive(Serialize, Deserialize, Validate, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PageParams {
    #[validate(range(min = 0))]
    page: u16,
    #[validate(range(min = 1, max = 100))]
    page_size: u8
}

If I have a web service with input param Json\<PageParams> and validation fails, I get a descriptive error message such as this:

Validation errors in fields: pageSize: range

However, if I have a web service with input param Json\<SearchParams> and validation fails on the same page_size field of the PageParams struct (nested validation), then the error message does not indicate which nested field failed validation or why:

Validation errors in fields:

kkharji commented 2 years ago

Any update on this one, as soon as I nested my request, tests failed. Thank god of TDD 😆 .

Roms1383 commented 2 years ago

I currently don't have time to look further into it but here's a suggestion.

When generating the error message, the script is iterating over field_errors() (as can be seen here) which is a method filtering errors of type ValidationErrorsKind::Field (as can be seen here : ok I'm pointing at the source code of a newer release, but it hasn't changed in the meantime as far as I can tell by looking in my IDE).

However I'd bet that failed validation in the nested struct triggers a ValidationErrorsKind::Struct instead (as can be seen here), hence why it doesn't show up in the generated error message.

Whoever wants to fix it might want to start by debugging it inside the impl ResponseError for Error and find out how the nested struct validation failure is represented inside the error.

Hope this helps.

Roms1383 commented 2 years ago

I opened a draft PR to illustrate (and provide a potential fix, see details): #35.