Gin: 未定義の検証関数 'がフィールドに存在します'

作成日 2019年11月29日  ·  3コメント  ·  ソース: gin-gonic/gin

説明

v1.4.0からv1.5.0にアップグレードしたところ、タグbinding:"exists"で内部サーバーエラーが発生しました

再現する方法

package main

import (
    "github.com/gin-gonic/gin"
)

type User struct {
    FirstName *string `json:"fn" binding:"exists"` 
}


func main(){
    router := gin.Default()
    router.POST("/register", func(c *gin.Context) {
        var user User
        if err := c.BindJSON(&user); err != nil {
            c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
                    "error": "first name cannot be empty",
                   })
            return
        }
    })

    router.Run(":8080")
}   

期待

return 400 with error message only if field FirstName is empty otherwise 200

実結果

2019/11/29 11:44:13 [Recovery] 2019/11/29 - 11:44:13 panic recovered:
Undefined validation function 'exists' on field 'FirstName'
/home/atif/go/src/github.com/go-playground/validator/cache.go:289 (0x7526b5)
        (*Validate).parseFieldTagsRecursive: panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
/home/atif/go/src/github.com/go-playground/validator/cache.go:150 (0x751319)
        (*Validate).extractStructCache: ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
/home/atif/go/src/github.com/go-playground/validator/validator.go:37 (0x7577bd)
        (*validate).validateStruct: cs = v.v.extractStructCache(current, typ.Name())
/home/atif/go/src/github.com/go-playground/validator/validator_instance.go:304 (0x75d706)
        (*Validate).StructCtx: vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
/home/atif/go/src/github.com/go-playground/validator/validator_instance.go:277 (0x8eb6ed)
        (*Validate).Struct: return v.StructCtx(context.Background(), s)
/home/atif/go/src/github.com/gin-gonic/gin/binding/default_validator.go:30 (0x8eb6b7)
        (*defaultValidator).ValidateStruct: if err := v.validate.Struct(obj); err != nil {
/home/atif/go/src/github.com/gin-gonic/gin/binding/binding.go:113 (0x8ef50c)
        validate: return Validator.ValidateStruct(obj)
/home/atif/go/src/github.com/gin-gonic/gin/binding/json.go:55 (0x8ef4c3)
        decodeJSON: return validate(obj)
/home/atif/go/src/github.com/gin-gonic/gin/binding/json.go:37 (0x8ef337)
        jsonBinding.Bind: return decodeJSON(req.Body, obj)
/home/atif/go/src/github.com/gin-gonic/gin/context.go:660 (0x8fc007)
        (*Context).ShouldBindWith: return b.Bind(c.Request, obj)
/home/atif/go/src/github.com/gin-gonic/gin/context.go:603 (0x8fbfd1)
        (*Context).MustBindWith: if err := c.ShouldBindWith(obj, b); err != nil {
/home/atif/go/src/github.com/gin-gonic/gin/context.go:566 (0xba6269)
        (*Context).BindJSON: return c.MustBindWith(obj, binding.JSON)
/home/atif/go/src/gitlab.com/atif/project/handlers/user.go:32 (0xba622f)
        (*Server).RegisterUser: if err := c.BindJSON(&u); err != nil {
/home/atif/go/src/github.com/gin-gonic/gin/context.go:147 (0x8f9859)
        (*Context).Next: c.handlers[c.index](c)
/home/atif/go/src/gitlab.com/atif/project/middlewares/auth.go:32 (0xbb6963)
        Auth.func1: c.Next()
/home/atif/go/src/github.com/gin-gonic/gin/context.go:147 (0x8f9859)
        (*Context).Next: c.handlers[c.index](c)
/home/atif/go/src/github.com/gin-gonic/gin/recovery.go:83 (0x90d179)
        RecoveryWithWriter.func1: c.Next()
/home/atif/go/src/github.com/gin-gonic/gin/context.go:147 (0x8f9859)
        (*Context).Next: c.handlers[c.index](c)
/home/atif/go/src/github.com/gin-gonic/gin/logger.go:241 (0x90c2a0)
        LoggerWithConfig.func1: c.Next()
/home/atif/go/src/github.com/gin-gonic/gin/context.go:147 (0x8f9859)
        (*Context).Next: c.handlers[c.index](c)
/home/atif/go/src/github.com/gin-gonic/gin/gin.go:411 (0x90381c)
        (*Engine).handleHTTPRequest: c.Next()
/home/atif/go/src/github.com/gin-gonic/gin/gin.go:369 (0x902f1d)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2774 (0x6cf5f7)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1878 (0x6cb1e0)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1337 (0x45f010)
        goexit: BYTE    $0x90   // NOP

環境

  • goバージョン:go1.12.6
  • ginバージョン(またはcommit ref):v1.5.0
  • オペレーティングシステム:linux / amd64

最も参考になるコメント

Gin.v1.4.0は検証にvalidator.v8を使用し、gin.v1.5.0はvalidator.v9を使用します。

したがって、次のように構造体を定義できます。
タイプUserstruct {
// FirstName * string json:"fn" binding:"exists"
FirstName * string json:"fn" binding:"required"
}

正しい結果が得られました。

全てのコメント3件

Gin.v1.4.0は検証にvalidator.v8を使用し、gin.v1.5.0はvalidator.v9を使用します。

したがって、次のように構造体を定義できます。
タイプUserstruct {
// FirstName * string json:"fn" binding:"exists"
FirstName * string json:"fn" binding:"required"
}

正しい結果が得られました。

ただし、 requiredではゼロ値は許可されません。 #491を参照

ゼロ値を許可する場合は、 *intを使用する必要があります。 この問題を参照してください。

このページは役に立ちましたか?
0 / 5 - 0 評価