go-playground / validator

:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
MIT License
16.83k stars 1.32k forks source link

Fail fast mode #1042

Open dcetenovic opened 1 year ago

dcetenovic commented 1 year ago

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

Enhancement

I have looked at the documentation and examples, didn't find an option to stop as soon as the first constraint violation occurs. This can be useful in various situations:

Example:

type NoName struct {
    Field1 string   `validate:"required"`
    Field2 string   `validate:"required,min=10,email"`
    Field3 []string `validate:"required,unique,max=1000,dive,ipv4"`
    Field4 string   `validate:"required,time_consuming_validation"`
}

func main() {
    v := validator.New()
    v.RegisterValidation("time_consuming_validation", func(fl validator.FieldLevel) bool {
        // run time consuming validation
        return false
    })

    err := v.Struct(NoName{
        Field1: "",
        Field2: "not email",
        Field3: []string{"127.0.0.1", "0.0.0.0"},
        Field4: "test",
    })
    fmt.Println(err)
}

Actual result: Key: 'NoName.Field1' Error:Field validation for 'Field1' failed on the 'required' tag Key: 'NoName.Field2' Error:Field validation for 'Field2' failed on the 'min' tag Key: 'NoName.Field4' Error:Field validation for 'Field4' failed on the 'time_consuming_validation' tag

Desired result: Key: 'NoName.Field1' Error:Field validation for 'Field1' failed on the 'required' tag

Validator should stop execution as soon as the first error occurs. Don't want to validate Field2, don't want to loop over Field3, don't want to run time_consuming_validation on Field4.

This behavior may be configurable:

v := validator.New()
v.FailFast()