Hi, i'm learning Gin and Go and thought i might get some insight from you guys.
I can't understand why Gin automatically sends an error 400 "Bad request" response when i try to bind and validate the incoming data from the a ajax request.
I set up a simple struct and set the "binding" to "required" on the Name field so it can be validated server-side :
type MyForm struct {
Name string `json:"name" binding:"required"
OtherField string `json:"otherfield"`
}
func HandleARoute(c *gin.Context) {
var form MyForm
err := c.BindJSON(&form)
if err == nil {
// if the binding is successful i save things to the database and return
// my custom JSON "success" message - this works as long as the
// binding is successful
c.JSON(http.StatusOK, gin.H{
"status": "success",
"msg": "Great, it was saved",
})
} else {
// THIS NEVER GETS SENT
// if the binding fails (e.g. the required field was not provided or any
// other error occured) i want to send my custom message but can't
// because Gin has already sent its own response that looks like this:
//
// {"msg":"Key: 'Stream.Name' Error:Field validation for 'Name' failed on the 'required' tag","status":"binding error"}
c.JSON(http.StatusOK, gin.H{
"status": "success",
"msg": "Great, it was saved",
})
}
}
So my question is, what is the right way to handle such errors so that i can send my own customized error message back to the browser ?
Sorry i found this issue discussed here: https://github.com/gin-gonic/gin/issues/633
Temporary solution, create a new package, copy the BindWith and BindJSON func from gin, comment out c.AbortWithError(400, err).SetType(ErrorTypeBind) and use
package ginfix
import (
"github.com/gin-gonic/gin/binding"
"github.com/gin-gonic/gin"
)
// BindJSON is a shortcut for c.BindWith(obj, binding.JSON)
func BindJSON(obj interface{}, c *gin.Context) error {
return BindWith(obj, binding.JSON, c)
}
// BindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func BindWith(obj interface{}, b binding.Binding, c *gin.Context) error {
if err := b.Bind(c.Request, obj); err != nil {
//c.AbortWithError(400, err).SetType(ErrorTypeBind)
return err
}
return nil
}
Most helpful comment
Temporary solution, create a new package, copy the
BindWithandBindJSONfunc from gin, comment outc.AbortWithError(400, err).SetType(ErrorTypeBind)and use