Validator: Custom validator fails on pointer?

Created on 1 Jun 2018  路  7Comments  路  Source: go-playground/validator

Package version eg. v8, v9:

v9

Issue, Question or Enhancement:

When I attempt to use a custom validator on a struct key that is a pointer, it always seems to fail, without actually running the validator.

Code sample, to showcase or reproduce:

Cut down example:

type Foo struct {
    Bar *string `json:"bar" validate:"fake"`
}

func FakeValidator(fl validator.FieldLevel) bool {
    fmt.Println("FakeValidator run")
    return true
}

func RegisterCustomValidators(validate *validator.Validate) {
    validate.RegisterValidation("fake", FakeValidator)
}

When I run this, I get the following output:

INFO[0003] main.Foo{Bar:(*string)(nil)}
ERRO[0003] error: validation error                       error="Key: 'Foo.Bar' Error:Field validation for 'Bar' failed on the 'fake' tag"

Note that FakeValidator run is never output anywhere.

If I change the definition of my struct to remove the pointer:

type Foo struct {
    Bar string `json:"bar" validate:"fake"`
}

Then I get the following (expected) output when I run:

INFO[0008] main.Foo{Bar:""}
FakeValidator run

I would expect that when I use my 'pointer' version, it should work the same way as the 'non-pointer version'. Basically I need to make my own version of the required tag as a custom validator.. but that determines whether it is required based on various rules. I had a look at the require code, and I don't see that it's any different to how I am approaching it, so can only assume that there is something 'higher up' that breaks it for my pointer version when using a custom validator.

enhancement v10

Most helpful comment

I see validator v9 has a new parameter for RegisterValidation called callValidationEvenIfNull. Should fix this issue if passing true, but I haven't tested it though:

https://godoc.org/gopkg.in/go-playground/validator.v9#Validate.RegisterValidation

All 7 comments

Hey @0xdevalias I haven't had time to prove it but I think it's because it gets into this block when it's a pointer and nil, most use cases incorporate required and omitempty which is probably why this hasn't come up before.

I will look into correcting the logic this weekend to support your use case and thanks for bringing this to my attention.

Sounds good, thanks :)

Just wanted to add a little extra context here in case i'm likely to run into another issue from here. I think the basic flows I want to implement is going to be something like:

IF customValidatorRequired THEN required
IF NOT customValidatorRequired THEN omitempty ELSE otherCustomValidators

I'm guessing I could probably build it up with the AND/OR operators, but not 100% how I would fit the omitempty part into it.

@0xdevalias it's sounding like it's a more complex validation, usually, once it get's complex enough I recommend using a Struct Level validation, and that way you can do whatever you want and also combine with the built-in validations.

Still looking into what else I can do with the initial problem, I'm a bit under the weather this weekend so not sure I'm going to get to it.

Do you think that the Struct Level validation will work in your situation?

Oo.. I think I must have mentally skipped over those.. They definitely do sound like they would work for what I need. Will play around with them and see. Thanks :)

Edit: Struct Level validation seems to have done the trick perfectly. Made all of the struct keys pointers, did the 'flow' validation at the StructLevel, and then can do omitempty + specific field validations for the ones that need it.

@0xdevalias glad that helped! I will look into incorporating this type of functionality into the next version 馃槃

I see validator v9 has a new parameter for RegisterValidation called callValidationEvenIfNull. Should fix this issue if passing true, but I haven't tested it though:

https://godoc.org/gopkg.in/go-playground/validator.v9#Validate.RegisterValidation

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timakin picture timakin  路  3Comments

donileo picture donileo  路  3Comments

0505gonzalez picture 0505gonzalez  路  3Comments

geraldstanje picture geraldstanje  路  5Comments

scisci picture scisci  路  5Comments