2017-10-05 99 views
-1

我有一个情况,当服务器将由于某种原因请求失败时,服务器将响应与json错误对象,服务器总是响应与HTTP 200.因此,如果我的令牌过期,我请求用户信息例如:不正确的JSON解析为结构没有错误

type Person struct { FirstName string LastName string }

非但没有 {"FirstName": "Bob", "LastName": "Smith"} 我提供{"error":401, "msg":"Unauthorized"}

我有一个函数,它interface{}解编:

func (ah *APIHandler) getObjectFromJson(bodyResponse string, target interface{}) *ServerError { 
    parsingError := json.NewDecoder(strings.NewReader(bodyResponse)).Decode(target) 
    // when server responds with ServerError I expect to get persingError here and proceed to unmarshalling the error message 
    if parsingError != nil { 
     fmt.Println(parsingError.Error()) 
     var err *ServerError = &ServerError{} 
     parsingError = json.NewDecoder(strings.NewReader(bodyResponse)).Decode(err) 
     if parsingError != nil { 
      // this means unmarshalling ServerError failed 
      panic(parsingError.Error()) 
     } 
     return err 
    } 
    return nil 
} 

付诸工作的例子,当我提供不正确JSON来传递interface{}我希望得到错误控制台“JSON不匹配结构”,不是空的结构。那可能吗?

我有超过50个模型,所以理想情况下,我想避免为他们每个人编写unmarshaller来检查字段是否已正确取消编组,我也想避免编写if strings.Contains(responseBody, "error"),因为某些对象可能包含字符串错误他们。解码时

https://play.golang.org/p/vecLomIXeB

+0

如果您不能嵌入模型或编写卸载器,您总是可以解码为一个'interface {}'映射:https://play.golang.org/p/ewks8sHz99。不是最好的解决方案。 – abhink

+0

@abhink是的,但看到我有+50模型,总共600个字段,不能手动完成。 – agilob

+0

另外:如果'* ServerError'实现'error',改变你的函数签名返回'error'。请参阅https://golang.org/doc/faq#nil_error – Peter

回答

4

标准库总是忽略未映射字段。这就是你想要的,因为否则你不能添加新的字段到你的模型,而不会打破这些模型的每个消费者。

不是检查无法识别的字段,而是检查响应是否包含错误字段,或者通过解组两次,或者通过解析除期望数据之外的错误字段。你已经这样做了,但你反其道而行之。

func (ah *APIHandler) getObjectFromJson(bodyResponse string, target interface{}) *ServerError { 
    b := []byte(bodyResponse) 

    se := &ServerError{} 
    if err := json.Unmarshal(b, &se); err != nil { 
      // ... 
    } 
    if se.Error != "" { 
      return se 
    } 

    if err := json.Unmarshal(b, target); err != nil { 
      // ... 
    } 

    return nil 
} 
+0

谢谢,好主意,比制作目标地图,然后将地图转换为结构更好,因为'ServerError'总是相同,但是'target '不是。 – agilob