Open renta opened 3 years ago
@deankarn Is any way I could help in solving this issue?
Yep @renta a PR to change to use errors.As in the example should do it :)
@deankarn Sorry for many words, but I'll try to specify issues that I've faced:
I've added if check that err is a type of validator.ValidationErrors like so:
func (v *Validator) Validate(toValidate interface{}) []string {
err := v.validate.Struct(toValidate)
var errs []string
if err != nil {
var valErrs validator.ValidationErrors
if errors.As(err, &valErrs) {
for _, e := range err.(validator.ValidationErrors) {
errs = append(errs, e.Translate(v.translator))
}
}
}
return errs
}
but looping still requires type assertion to explain the compiler that err would be of ValidationErrors type because as it said in Struct method docs:
It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
So errorlint continue to argue on this code. Is there a way to explicitly convert err from validate.Struct to validator.ValidationErrors without assertion? Or maybe I should ask polyfloyd/go-errorlint to check that errors.As wrap underlying error type assertion, so there could not be issue with error wrapping in code like this?
Hello @renta,
I came across your issue and found out you don't need type assertions to loop over the slice, you could use it like this:
func (v *Validator) Validate(toValidate interface{}) []string {
err := v.validate.Struct(toValidate)
var errs []string
if err != nil {
var valErrs validator.ValidationErrors
if errors.As(err, &valErrs) {
for _, e := range valErrs {
errs = append(errs, e.Translate(v.translator))
}
}
}
return errs
}
As mentioned in the documentation of pkg/errors:
sets target to that error value and returns true.
errors.As(...)
could return true and err.(validator.ValidationErrors)
could not work if the error was wrapped.
Thank you for the answer @rotta-f ! @deankarn What do you think of using this code example in the Readme of the library?
This code in the golang documentation throws this error:
https://pkg.go.dev/github.com/pkg/errors#section-readme
type stackTracer interface {
StackTrace() errors.StackTrace
}
if err, ok := err.(stackTracer); ok {
for _, f := range err.StackTrace() {
fmt.Printf("%+s:%d\n", f, f)
}
}
Do you have a better suggestion for writing this function?
How can I suppress this error if I don't agree with it?
I suppose like this?
type stackTracer interface {
StackTrace() errors.StackTrace
}
var stackErr stackTracer
if errors.As(err, &stackTracer) {
for _, f := range stackErr.StackTrace() {
fmt.Printf("%+s:%d\n", f, f)
}
}
Package version eg. v9, v10:
Issue, Question or Enhancement:
Golangci-lint (https://github.com/golangci/golangci-lint) comes with a errorlint linter (https://github.com/polyfloyd/go-errorlint). When I switched it on, I got this issue from the linter:
Is there a way to change err.(validator.ValidationErrors) on errors.As as suggested linter or it's a false-positive issue? Because I could not find examples other than err.(validator.ValidationErrors) in this repo.
Code sample, to showcase or reproduce: