go从0到1项目实战体系三十二:参数绑定error

1. 访问url /v1/admin/books?size=abc:

. 返回结果:
	a. {"error": "param errorstrconv.ParseInt: parsing \"abc\": invalid syntax"}
	b. network查看code也是400,但是代码里面是500?. 控制台日志:
   [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500
   [GIN] 2020/08/09 - 21:30:57 | 500 |   209.632µs |  ::1 | GET   "/v1/admin/books?size=abc"
   a.500重写成400

(1). 原因分析:

func CreateBookListRequest() Lib.EncodeRequestFunc {
	return func(ctx *gin.Context) (i interface{}, e error) {
		req := &BookListRequest{}
		// 这里返回了错误信息
		if err := ctx.BindQuery(req); err != nil {
			return nil, err
		}
		return req, nil
	}
}. 点击BindQuery查看源码:
    // BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
	func (c *Context) BindQuery(obj interface{}) error {
		return c.MustBindWith(obj, binding.Query)
	}. 点击MustBindWith查看源码:
	// MustBindWith binds the passed struct pointer using the specified binding engine.
	// It will abort the request with HTTP 400 if any error occurs.
	// See the binding package.
	func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
		if err := c.ShouldBindWith(obj, b); err != nil {
			// http.StatusBadRequest的常量就是400
			c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
			return err
		}
		return nil
	}

(2). 怎样自定义返回code呢?

. 将BindQuery修改为ShouldBindQuery:
    // ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
	func (c *Context) ShouldBindQuery(obj interface{}) error {
		return c.ShouldBindWith(obj, binding.Query)
	}

	// 点击ShouldBindWith查看源码:
	// ShouldBindWith binds the passed struct pointer using the specified binding engine.
	// See the binding package.
	func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
		return b.Bind(c.Request, obj)
	}. BindUri修改为ShouldBindUri:
	// ShouldBindUri binds the passed struct pointer using the specified binding engine.
	func (c *Context) ShouldBindUri(obj interface{}) error {
		m := make(map[string][]string)
		for _, v := range c.Params {
			m[v.Key] = []string{v.Value}
		}
		return binding.Uri.BindUri(m, obj)
	}

你可能感兴趣的:(golang,微服务,系统架构,gin,后端,go,开发语言)