Keats / validator

Simple validation for Rust structs
MIT License
1.98k stars 142 forks source link

Easy way to get a Vec<ValidationError> #80

Open jamessewell opened 4 years ago

jamessewell commented 4 years ago

I'm using nested validations, and it would be great if there was a simple way to get at the ValidationError objects.

At the moment it's obscured by the many levels of ValidationErrors

Keats commented 4 years ago

How would that work? A ValidationError doesn't have the name of the field the error is on so you would get a bunch of errors but not know where it actually comes from.

jamessewell commented 4 years ago

True.

How about a human readable display for the whole thing?

On Wed, 25 Sep 2019 at 2:28 am, Vincent Prouillet notifications@github.com wrote:

How would that work? A ValidationError doesn't have the name of the field the error is on so you would get a bunch of errors but not know where it actually comes from.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Keats/validator/issues/80?email_source=notifications&email_token=AAJJDI2J4YMT2L4X74EVNO3QLI52NA5CNFSM4IZ3QEJ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7O645I#issuecomment-534638197, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJJDIYHVVT7GTSKJK7SYTLQLI52NANCNFSM4IZ3QEJQ .

jamessewell commented 4 years ago

Ok so thinking about this more I would really love something like what serde_json does:

Json deserialize error: unknown field `orthing`, expected `easting` or `northing` at line 1 column 365

But I suppose you need proper serde hooks to get line and column info.

Maybe something like:

Validate error: field `easting`, value 181 is not between -180 and +180

Sure it doesn't include any of the nesting information, but it's good enough for the majority of cases.

incker commented 4 years ago

You can get a field name, my code snipet:

    my_struct.validate().map_err(|err: ValidationErrors| {
        let errors: HashMap<&str, validator::ValidationErrorsKind> = err.into_errors();
        for (field, err) in errors {
            // do what you need
        }
    })

I it good thing if you will make own wrapper over validator

And by the way, @jamessewell, you can make custom message errors, like #[validate(length(min = 1, max = 255, message = "your good readable error"))]

vasilakisfil commented 4 years ago

How would that work? A ValidationError doesn't have the name of the field the error is on so you would get a bunch of errors but not know where it actually comes from.

I am wondering what lead to such design, that is, why ValidationError doesn't hold the param key ? That makes ValidationError struct in isolation useless.

Cool crate though!

Keats commented 4 years ago

Not all errors have a key. For example what would be the param key for a failed validation of the second string in a vec of a nested key? It could be an Option but it wouldn't be that great either since it would only be there in some cases.

dyedgreen commented 3 years ago

I was also running into this issue. It would really help in my case, if the error Display was more presentable, such that it could e.g. be echoed out directly to users. (Example use case would be returning this error from a GraphQL api, and just displaying the error on the client side.)

@Keats I was thinking about a format similar to this:

Format individual errors

match (message, code) {
  (None, None) => /* some default format, e.g. value 181 is not between -180 and +180 */,
  (Some(msg), None) => msg.to_string(),
  (Some(msg), Some(code)) => format!("{} ({})", msg, code),
}

Format ValidationErrors collection

The final display output should look something like this:

field: My error message (5)
nested.field: My other message
field.in.array.[2]: {default format here}

Would be happy to try and implement something like this if you're interested!

Keats commented 3 years ago

I'm ok having a better Display implementation but relying on it to display errors to end users would be bad imo. You want to co-locate the field error to the field, it's maddening otherwise.

singulared commented 2 years ago

Maybe it can be helpful for you: https://github.com/rambler-digital-solutions/actix-web-validator/blob/master/src/error.rs#L65