#go
#Вперед
Вопрос:
Я создаю API
в go
. Все работает нормально, только когда возникает ошибка, я хочу показать ее пользователю. Я использую errors
пакет go.
Ниже приведен 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))
Ответ, который я получаю, является:
{
"status": "ERROR",
"error": {} //why is this empty
}
ключ ошибки должен содержать строку Total Price cannot be a negative value
. Я не понимаю проблему.
Комментарии:
1. Вы не можете отправить данные после http. Ошибка: См. golang.org/pkg/net/http/#Error . Вы должны отправить
string(response)
вместоhttp.StatusText(500)
. Это действительно помогает прочитать всю документацию по любой используемой функции.2.
if err != nil { log.Fatal(err) http.Error(w, http.StatusText(500), 500) return }
Я не говорю об этой ошибке. Эта обработка ошибок предназначена для сбоя, еслиjson.Marshal
. Пожалуйста, прочитайте контекст должным образом, прежде чем отклонять.3. @Volker Я отредактировал свой вопрос, если вы в замешательстве. Пожалуйста, проверьте.
Ответ №1:
Типы ошибок не могут маршалироваться в JSON. Есть несколько способов обойти это. Если вы не хотите изменять свою ErrorResponse
структуру, то практически единственный способ — определить пользовательский MarshalJSON
метод для вашей структуры, в котором вы указываете маршалеру использовать строку, возвращаемую .Error()
методом ошибки.
func (resp ErrorResponse) MarshalJSON() ([]byte, error) {
return json.Marshal(amp;struct {
Status string `json:"status"`
Error string `json:"error"`
}{
Status: resp.Status,
Error: resp.Error.Error(),
})
}
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())
}
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))
Обратите внимание, что в случае сбоя маршалинга вам все равно следует написать какой-то ответ перед возвратом.