Better bind error messages

This commit is contained in:
Manu Mtz-Almeida 2015-05-23 03:10:15 +02:00
parent 35fd7fb480
commit 784d73477d
2 changed files with 48 additions and 0 deletions

View File

@ -268,6 +268,7 @@ func (c *Context) BindJSON(obj interface{}) error {
func (c *Context) BindWith(obj interface{}, b binding.Binding) error { func (c *Context) BindWith(obj interface{}, b binding.Binding) error {
if err := b.Bind(c.Request, obj); err != nil { if err := b.Bind(c.Request, obj); err != nil {
err = parseBindError(err)
c.AbortWithError(400, err).SetType(ErrorTypeBind) c.AbortWithError(400, err).SetType(ErrorTypeBind)
return err return err
} }

View File

@ -5,12 +5,15 @@
package gin package gin
import ( import (
"bytes"
"encoding/xml" "encoding/xml"
"net/http" "net/http"
"path" "path"
"reflect" "reflect"
"runtime" "runtime"
"strings" "strings"
"gopkg.in/bluesuncorp/validator.v5"
) )
func WrapF(f http.HandlerFunc) HandlerFunc { func WrapF(f http.HandlerFunc) HandlerFunc {
@ -51,6 +54,50 @@ func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
return nil return nil
} }
func parseBindError(err error) error {
switch err.(type) {
case *validator.StructErrors:
unwrapped := err.(*validator.StructErrors)
fields := listOfField(unwrapped.Errors)
humanError := tohuman(fields)
return &Error{
Err: unwrapped,
Type: ErrorTypeBind,
Meta: H{
"message": humanError,
"fields": fields,
},
}
default:
return err
}
}
func listOfField(errors map[string]*validator.FieldError) []string {
fields := make([]string, 0, len(errors))
for key := range errors {
fields = append(fields, strings.ToLower(key))
}
return fields
}
func tohuman(fields []string) string {
length := len(fields)
var buf bytes.Buffer
if length > 1 {
buf.WriteString(strings.Join(fields[:length-1], ", "))
buf.WriteString(" and ")
}
buf.WriteString(fields[length-1])
if len(fields) == 1 {
buf.WriteString(" is ")
} else {
buf.WriteString(" are ")
}
buf.WriteString("required.")
return buf.String()
}
func filterFlags(content string) string { func filterFlags(content string) string {
for i, char := range content { for i, char := range content {
if char == ' ' || char == ';' { if char == ' ' || char == ';' {