Можете ли вы вернуть json в golang http.Error? - PullRequest
0 голосов
/ 16 января 2020

Можете ли вы вернуть json, когда вызывается http.Error?

        myObj := MyObj{
            MyVar: myVar}

        data, err := json.Marshal(myObj)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return 
        }
        w.Write(data)
        w.Header().Set("Content-Type", "application/json")

        http.Error(w, "some error happened", http.StatusInternalServerError)

Я вижу, что он возвращает 200 без json, но json вставляется в text

Ответы [ 3 ]

3 голосов
/ 16 января 2020

Это должен быть только простой текст.

Из документов

fun c Ошибка (w ResponseWriter, строка ошибки, код int)

Ошибка отвечает на запрос с указанное сообщение об ошибке и код HTTP. В противном случае запрос не заканчивается; вызывающая сторона должна убедиться, что дальнейшие записи в w не выполняются. Сообщение об ошибке должно быть простым текстом.

Также я думаю, что вы используете http.Error не правильно. Когда вы звоните w.Write(data), ответ отправляется, и тело ответа будет закрыто. Вот почему вы получаете статус 200 вместо 500 от http.Error.

Вместо использования http.Error вы можете отправить свой собственный ответ об ошибке с помощью json, как если бы вы отправляли любой другой ответ установка кода состояния на код ошибки.

2 голосов
/ 16 января 2020

Я обнаружил, что действительно легко прочитать источник Go. Если вы щелкнете по функции в документе, вы попадете к источнику для функции Error: https://golang.org/src/net/http/server.go?s=61907: 61959 # L2006

// Error replies to the request with the specified error message and HTTP code.
// It does not otherwise end the request; the caller should ensure no further
// writes are done to w.
// The error message should be plain text.
func Error(w ResponseWriter, error string, code int) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.Header().Set("X-Content-Type-Options", "nosniff")
    w.WriteHeader(code)
    fmt.Fprintln(w, error)
}

Так что если вы хотите чтобы вернуть JSON, достаточно написать собственную функцию Error.

func JSONError(w http.ResponseWriter, err interface{}, code int) {
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    w.Header().Set("X-Content-Type-Options", "nosniff")
    w.WriteHeader(code)
    json.NewEncoder(w).Encode(err)
}
0 голосов
/ 17 января 2020

Как сказал @ShashankV, вы пишете ответ неправильно. В качестве примера, вот что я сделал во время обучения написанию RESTful API, обслуживающего в Golang:

type Response struct {
    StatusCode int
    Msg string
}

func respond(w http.ResponseWriter, r Response) {
    // if r.StatusCode == http.StatusUnauthorized {
    //     w.Header().Add("WWW-Authenticate", `Basic realm="Authorization Required"`)
    // }

    data, err := json.Marshal(r)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprintf(w, err.Error())
        return 
    }

    w.WriteHeader(r.StatusCode)
    fmt.Fprintf(w, r.Msg)
}

func Hello(w http.ResponseWriter, r *http.Request) {
    resp := Response{http.StatusOK, welcome}
    respond(w, resp)
}

Ref: https://github.com/shudipta/Book-Server/blob/master/book_server/book_server.go

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...