2017-10-05 86 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