Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom validation tag is ignored when validating a field that is of type struct #367

Closed
codasols opened this issue May 23, 2018 · 3 comments · Fixed by #1122 · May be fixed by #668
Closed

Custom validation tag is ignored when validating a field that is of type struct #367

codasols opened this issue May 23, 2018 · 3 comments · Fixed by #1122 · May be fixed by #668
Assignees

Comments

@codasols
Copy link

Package version eg. v8, v9:

v9

Issue, Question or Enhancement:

The custom validation tag appears to have no impact when it is used against a field that is of type struct. If the tag is not registered, the validator library panics as expected, however if the tag is registered and deliberately set to return false, I would expect validation to fail.

However it does not.

Is this intended behaviour? Can field validation not be performed in this way? If I was to use my custom tag against a standard system type, such as a string, the validation fails as expected.

Apologies if this is covered in the documentation somewhere.

Code sample, to showcase or reproduce:

package main

import (
	"fmt"
	"time"

	validator "gopkg.in/go-playground/validator.v9"
)

// We want to validate the ValidUntil is equal to or after ValidFrom

type Record struct {
	ValidFrom  ExtendedDate `validate:"required"`
	ValidUntil ExtendedDate `validate:"required,gteEpoch=ValidFrom"`
}

type ExtendedDate struct {
	Epoch   int64     `validate:"required"`
	Iso6801 time.Time `validate:"required"`
}

var validate *validator.Validate

func main() {

	record := Record{
		ValidFrom: ExtendedDate{
			Epoch:   1,
			Iso6801: time.Now(),
		},
		ValidUntil: ExtendedDate{
			Epoch:   1,
			Iso6801: time.Now().AddDate(0, 0, -1),
		},
	}

	validate = validator.New()
	validate.RegisterValidation("gteEpoch", gteEpoch)

	err := validate.Struct(record)

	// This should fail, but it does not?
	if err != nil {
		fmt.Printf("%v\n", err.Error())
	}
}

func gteEpoch(fl validator.FieldLevel) bool {
	// Perform required validation checks here...

	// Deliberately fail here for this example
	return false
}
@deankarn deankarn self-assigned this May 24, 2018
@deankarn
Copy link
Contributor

@ptcoda I will try to take a look this week.

@deankarn
Copy link
Contributor

deankarn commented Jun 5, 2018

Hey @ptcoda sorry for the delay, I was looking deep into the code and to make this work properly will definitely be a breaking change, I did not anticipate this specific use case; I will add this to the list of v10 improvements :)

however, not to fret, all is not lost, this is actually a perfect use case for Struct Level validation; I would add a validation for your Record struct.

Please let me know if this will help :)

@alecthomas
Copy link

I just hit the same problem, but I don't think this can be solved by Struct Level validation as far as I can tell. The problem is that the validator (in this case gteEpoch=ValidFrom) is set on the parent field, but struct level validators don't have access to this. Am I mistaken here?

PS. Great library, thanks!

@zenovich zenovich mentioned this issue Mar 10, 2020
1 task
deankarn pushed a commit that referenced this issue Aug 6, 2023
## Fixes #367, #906

**Make sure that you've checked the boxes below before you submit PR:**
- [x] Tests exist or have been written that cover this particular
change.

A test has been added for custom tags, however I was not brave enough to
actually update the tests for all required/excluded tag variants before
getting an initial feedback, but I'm willing to do so if this ever gets
any further.

Same goes for documentation.

The implementation supports both struct and struct pointer validations
for custom tags and all required/excluded tag variants.

Struct validity is evaluated first and fields are evaluated only if the
struct is valid, though I'm not sure if this is the desired behavior.

@go-playground/validator-maintainers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment