2017-07-08 32 views
4

我想爲某個REST API編碼一些JSON,除了一些錯誤,一切工作正常。例如,這個結構:當編碼爲JSON時,Golang錯誤類型爲空

type TemplateResponse struct { 
    Message string 
    Error error 
    Template Template 
} 

與此數據編碼:

res := TemplateResponse{"Template not found.", fmt.Errorf("There is no template on this host with the name " + vars["name"]), Template{}} 
json.NewEncoder(w).Encode(res) 

返回:

{ 
    "Message": "Template not found.", 
    "Error": {}, 
    "Template": { 
    "Name": "", 
    "Disabled": false, 
    "Path": "", 
    "Version": "" 
    } 
} 

我在我的應用程序獲得這個看似隨機,其中 '錯誤'類型被返回爲空。有任何想法嗎?

謝謝!

回答

7

因爲error只是一個接口。它可以保存實現它的任何具體類型的值。

在您的示例中,您使用了fmt.Errorf()來創建error值。它調用errors.New(),它返回一個指向未導出的errors.errorString結構值的指針。它的定義是:

type errorString struct { 
    s string 
} 

這個結構值將被封,但因爲它沒有出口領域(僅導出字段編組),這將是一個空的JSON對象:{}

「修復」是:不要封送「通用」接口的值,依靠動態值可以封送到JSON有意義。相反,你應該從編組添加存儲錯誤字符串(的error.Error()結果)字段,並省略Error error領域,如:

type TemplateResponse struct { 
    Message string 
    Error error `json:"-"` 
    ErrorMsg string 
    Template Template 
} 

當然,你還需要設置/編組前填寫ErrorMsg場。

或者,如果你並不需要保存在結構中的error值,刪除該領域徹底:

type TemplateResponse struct { 
    Message string 
    ErrorMsg string 
    Template Template 
} 

如果你仍然想保持Error error場(而不是ErrorMsg場),然後您需要通過實現json.Marshaler接口來實現自定義編組邏輯,您可以在其中將「error」值「轉換」爲有意義的string(或轉換爲可以正確編組的其他值)。

+0

完美感。非常感謝這個偉大的解釋! – putitonmytab