Go中的错误处理在http响应中返回空错误对象

Jag*_*ati 0 go

我创建APIgo.一切正常,只有在出现错误时我才想向用户展示.我正在使用go的errors包.

以下是sample代码:

type ErrorResponse struct {
        Status string `json:"status"`
        Error  error  `json:"error"`
    }
err := errors.New("Total Price cannot be a negative value")
errRes := ErrorResponse{"ERROR", err}
response, errr := json.Marshal(errRes)
if errr != nil {
    log.Fatal(err)
    return
}
io.WriteString(w, string(response))
Run Code Online (Sandbox Code Playgroud)

我得到的回应是:

{
  "status": "ERROR",
  "error": {} //why is this empty
}
Run Code Online (Sandbox Code Playgroud)

错误键应该有字符串Total Price cannot be a negative value.我不明白这个问题.

jus*_*ius 5

错误类型无法将自己编组为JSON.有几种方法可以解决这个问题.如果您不想更改ErrorResponse结构,那么几乎唯一的方法是MarshalJSON为您的结构定义一个自定义方法,您可以告诉编组程序使用Error .Error()方法返回的字符串.

func (resp ErrorResponse) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        Status string `json:"status"`
        Error  string `json:"error"`
    }{
        Status: resp.Status,
        Error:  resp.Error.Error(),
    })
}
Run Code Online (Sandbox Code Playgroud)

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

如果你想在其他地方将错误编组到JSON中.然后,您可以使用自定义错误类型并为其定义编组,例如:

type MyError struct {
    Error error
}

func (err MyError) MarshalJSON() ([]byte, error) {
    return json.Marshal(err.Error.Error())
}
Run Code Online (Sandbox Code Playgroud)

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

最简单(也可能是最好的)方法是在响应结构中使用一个字符串.这是有道理的,因为您在http响应中发送的实际值显然是字符串,而不是错误接口.

type ErrorResponse struct {
        Status string `json:"status"`
        Error  string  `json:"error"`
    }
err := errors.New("Total Price cannot be a negative value")
errRes := ErrorResponse{"ERROR", err.Error()}
response, errr := json.Marshal(errRes)
if errr != nil {
    log.Fatal(err)
    // you should write something to responseWriter w here before returning
    http.Error(w, "Internal server error", http.StatusInternalServerError)
    return
}
io.WriteString(w, string(response))
Run Code Online (Sandbox Code Playgroud)

请注意,如果编组失败,您仍应在返回之前编写某种响应.