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

Valid request throws error: Interface conversion error is nil not validator.validationerrors for valid request body #20

Open
aymanapatel opened this issue Jul 11, 2020 · 3 comments

Comments

@aymanapatel
Copy link

Issue

The below validator works for invalid request body, but for a valid body, it initiates a panic

Code sample, to showcase or reproduce:

data/validation.go

func (v *Validation) Validate(i interface{}) ValidationErrors {
	errs := v.validate.Struct(i).(validator.ValidationErrors)

	if len(errs) == 0 {
		return nil
	}

	var returnErrs []ValidationError
	for _, err := range errs {
		// cast the FieldError into our ValidationError and append to the slice
		ve := ValidationError{err.(validator.FieldError)}
		returnErrs = append(returnErrs, ve)
	}

	return returnErrs
}

handlers/post.go :

func (p *Products) Create(rw http.ResponseWriter, r *http.Request) {
	prod := r.Context().Value(KeyProduct{}).(data.Product) // Panic originate here. Check below for struct definiton

	p.l.Printf("[DEBUG] Inserting product: %#v\n", prod)
	data.AddProduct(prod)
}

data/products.go

// data.Product
type Product struct {

	ID int `json:"id"` // Unique identifier for the product

	Name string `json:"name" validate:"required"`

	Description string `json:"description"`

	SKU string `json:"sku" validate:"sku"`
}

Stack Trace:

products-api 2020/07/04 17:04:27 http: panic serving 127.0.0.1:47468: interface conversion: interface {} is *data.Product, not data.Product
goroutine 50 [running]:
net/http.(*conn).serve.func1(0xc0005fe0a0)
        /usr/local/go/src/net/http/server.go:1772 +0x139
panic(0x951fe0, 0xc00030a480)
        /usr/local/go/src/runtime/panic.go:973 +0x3e3
github.com/nicholasjackson/building-microservices-youtube/product-api/handlers.(*Products).Create(0xc0003192c0, 0xaa9320, 0xc00046a000, 0xc000400400)
        /tmp/building-microservices-youtube/product-api/handlers/post.go:20 +0x349
net/http.HandlerFunc.ServeHTTP(0xc000319510, 0xaa9320, 0xc00046a000, 0xc000400400)
        /usr/local/go/src/net/http/server.go:2012 +0x44
github.com/nicholasjackson/building-microservices-youtube/product-api/handlers.(*Products).MiddlewareValidateProduct.func1(0xaa9320, 0xc00046a000, 0xc000400200)
        /tmp/building-microservices-youtube/product-api/handlers/middleware.go:42 +0x553
net/http.HandlerFunc.ServeHTTP(0xc00027c0a0, 0xaa9320, 0xc00046a000, 0xc000400200)
        /usr/local/go/src/net/http/server.go:2012 +0x44
github.com/gorilla/mux.(*Router).ServeHTTP(0xc000156300, 0xaa9320, 0xc00046a000, 0xc000400000)
        /home/ayman/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:212 +0xe2
net/http.serverHandler.ServeHTTP(0xc00055c1c0, 0xaa9320, 0xc00046a000, 0xc000400000)
        /usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0005fe0a0, 0xaaa460, 0xc00021c040)
        /usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
        /usr/local/go/src/net/http/server.go:2933 +0x35c

Could it be the version 10 from go validator has broken the implementation? I have cloned your repo and checked out episode_7 branch and it throws the above error for valid requests.

@dbarochiya
Copy link

Was facing the same issue - able to resolve it by following the solution - is it just because we are casting the error to nil ?

 errs := v.validate.Struct(i).(validator.ValidationErrors)

According to blow link this should work ?

https://stackoverflow.com/questions/29138591/hiding-nil-values-understanding-why-golang-fails-here/29138676#29138676

@kartikra
Copy link

kartikra commented May 29, 2022

// Refer: https://github.com/go-playground/validator/issues/632
func (v *Validation) Validate(i interface{}) ValidationErrors {
	var returnErrs []ValidationError
	if errs, ok := v.validate.Struct(i).(validator.ValidationErrors); ok {
	
		if errs != nil {
			for _, err := range errs {
				if fe, ok := err.(validator.FieldError); ok {
					ve := ValidationError{fe}
					returnErrs = append(returnErrs, ve)
				}
			}
		}
	}
	
	return returnErrs
}

@kartikra
Copy link

@nicholasjackson can you please update the Validate function under data/validation.go (from episode_7 branch and above)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants