【问题标题】:How can I catch a marshalling error in Go? [duplicate]如何在 Go 中捕获编组错误? [复制]
【发布时间】:2020-02-16 15:00:32
【问题描述】:

我有一个 API 需要 "username":"string" 请求正文,我正在将请求正文解组为符合我期望的用户结构。我的代码不会对不匹配的结构数据引发错误。有没有我可以使用的函数来代替 json.Unmarshal?如果不是,在这种情况下我怎么能捕捉到 400 错误? (我也尝试过使用 json.decoder)

这是我的代码:

type User struct {
   Username string `json:"username" gorm:"primary_key;Column:username"`
}

var user models.User

body, err := ioutil.ReadAll(r.Body)
if err = json.Unmarshal(body, &user); err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
}

【问题讨论】:

    标签: go


    【解决方案1】:

    您可以使用json.DecoderDisallowUnknownFields 选项在解码器发现不在结构中的字段时导致错误:

    DisallowUnknownFields 导致解码器在目标是结构并且输入包含与目标中任何未忽略的导出字段不匹配的对象键时返回错误。

    【讨论】:

      【解决方案2】:

      如果您想同时确保键 "username" 存在,而其他字段不存在,则需要实现 Unmarshaler 接口,并遍历所有接收到的键。

      func (user *User) UnmarshalJSON(data []byte) (error) {                                                    
          d := make(map[string]interface{})                                                                                                    
          err = json.Unmarshal(data, &d)                                                                         
          if err != nil {                                                                                               
              return err
          }
          if _, ok := d["username"]; !ok {
              return fmt.Errorf("username is required")
          }
          for k, v := range d {
              if k == "username" {
                  username, ok := v.(string)
                  if !ok {
                      return fmt.Errorf("username must be a string, got %T", v)
                  }
                  user.Username = username
              } else {
                  return fmt.Errorf("Unexpected key %s", k)
              }
          }
          return                                                                                                  
      }       
      

      【讨论】:

        猜你喜欢
        • 2019-12-10
        • 2017-07-25
        • 1970-01-01
        • 2012-02-21
        • 2019-02-12
        • 1970-01-01
        • 2020-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多