gin: Working with BindJSON and error return
Hello,
First of all, thanks for your great project, I’m using it a on daily basis and it’s just awesome.
TL;DR
I have no clue on how to properly handle response format when validation fails on BindJSON and I want to send back the errors as JSON.
Context
I’m currently having trouble working with context.BindJSON. I have two fields that are required when receiving JSON, let’s call them first and second
type params struct {
First string `json:"first" binding:"required"`
Second string `json:"second" binding:"required"`
}
Now when I receive the request, I handle it like this :
func postFirstSecond(c *gin.Context) {
var err error
c.Header("Content-Type", "application/json; charset=utf-8")
p := params{}
if err = c.BindJSON(&p); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "json decoding : " + err.Error(),
"status": http.StatusBadRequest,
})
return
}
}
So first of all, I don’t understand why c.JSON() doesn’t return the appropriate content-type, I found that when BindJSON fails, it writes the header to be plain text. Anyway my endpoint always returns JSON so I just set the content-type on top of the handler, problem solved (I guess).
When one field is missing, this endpoint returns something like that :
{
"error": "json decoding : Key: 'params.First' Error:Field validation for 'First' failed on the 'required' tag",
"status": 400
}
That’s fine. I mean it’s not really what I expected but it works.
Problem
When both fields are missing, this is what I get back :
{
"error": "json decoding : Key: 'params.First' Error:Field validation for 'First' failed on the 'required' tag\nKey: 'params.Second' Error:Field validation for 'Second' failed on the 'required' tag",
"status": 400
}
Question
Is there a simple way to handle those errors ? I’d like to get something more user-friendly, or at least a separate field for my errors. Something like :
{
"errors": [
"Key: 'params.First' Error:Field validation for 'First' failed on the 'required' tag",
"Key: 'params.Second' Error:Field validation for 'Second' failed on the 'required' tag"
],
"status": 400
}
I’m aware that checking manually the fields should allow me to do that, but the fact is : I feel like the documentation and examples are pretty vague about error handling.
Could someone help me with that ? How do you handle errors generated by Bind or BindJSON ?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 13
- Comments: 18 (4 by maintainers)
@mymtw if you want to get Content-Type
application/jsonheader when validating failed , you can useShouldBindWithinstead ofBindfunction that will not call AbortWithError.ref: https://github.com/gin-gonic/gin/issues/1041#issuecomment-319125864
I also experience the error that the ‘Content-Type’ is text/plain instead of ‘application/json’ when I have a binding error and return a error struct using
c.JSON()Yes you are correct @toefel18 not all errors that can be returned are
ValidationErrorssome are related to, as you pointed out,Content-Typeand also JSON decoding errors.so one would have to ensure the cast succeeds: