binding icon indicating copy to clipboard operation
binding copied to clipboard

Don't convert non-binding.Errors.

Open snargleplax opened this issue 7 years ago • 2 comments

As a follow-on to 52f4dd9, continue the process of allowing errors that aren't binding.Errors to flow through without adaptation.

The need for this arises from cases where validation is performed against a struct that contains field of a struct type that also implements Validator, when the validation for the inner type returns an error that isn't a binding.Errors. The existing code consumes such errors and turns them into not-particularly-helpful binding.Errors instances, inhibiting upstack processing of distinct error types. This does away with that interference.

snargleplax avatar Mar 28 '18 23:03 snargleplax

Thank you for contributing.

I'd prefer not to merge this. Preserving errors going back up the stack is not a goal of this project. Checking for sentinel errors and error types are unfortunate anti-patterns that have their roots in the the standard library.

But you're not left with no path forward. By implementing Binder and/or Validator, you can capture the originating errors to be inspected if you want. Consider:

type UserBinding struct {
    Name string
    OrgID int
    err error
    org OrgService
}

func (u *UserBinding) Validate(r *http.Request) error {
    users, err := u.org.Users()
    if err != nil {
        u.err = err
        return
    }
    
    if users.Has(u.Name) {
        return binding.NewError("name", "duplicate", "user already exists")
    }
    return nil
}

Errors are just values and can be treated like any other value; they can be captured, inspected, closed over, etc. Unless an API says otherwise, one cannot assume that errors are returned unaltered all the way up the stack.

bhcleek avatar Apr 12 '18 04:04 bhcleek

I'm trying to figure out a way to integrate this without introducing inconsistencies in user's experiences between validation and binding. The work you've done here, will return errors from the binding functions (e.g. Bind, Form, Json) unaltered if the errors came from the a Validator. But that won't hold for Binder implementations (see https://github.com/mholt/binding/blob/master/binding.go#L437). 🤔

bhcleek avatar Apr 12 '18 04:04 bhcleek