Если в функции http.handlerfunc возникает паника, она не будет отправлена ​​клиенту с кодом состояния http.

Если в функции http.HandlerFunc возникает паника, она не будет отправлена ​​на клиентский код состояния http. Почему это так и как этого избежать? Поскольку javascript XMLHttpRequest не работает должным образом, если он не получает код состояния http.

Как написать запрос ajax для ситуаций, когда HTTP-ответ не имеет состояния и содержимого тела?

func main() {
    var counter int

    http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
        if counter%2 == 0 {
            counter++
            writer.Write([]byte(time.Now().String()))
        } else {
            counter++
            panic(":(")
        }
    })

    err := http.ListenAndServe(":9999", nil)
    if err != nil {
        panic(err)
    }
}

1. Не используйте panic. 2. Если это какая-то другая библиотека - восстановитесь после паники, затем войдите в журнал и верните HTTP 500.

zerkms 26.10.2018 05:37

"он не будет отправлен клиенту с кодом статуса http" Как вы думаете, почему это правда? Как вы думаете, что происходит? Ты пробовал? Если пробовали: Что бывает делал?

Volker 26.10.2018 07:05
0
2
503
1

Ответы 1

В этом случае не стоит впадать в панику. Паника приведет к тому, что текущая процедура go, запускающая функцию вашего обработчика, завершится без записи в ответ чего-либо, чего вы не хотите, вместо этого вернет код ошибки с помощью метода WriteHeader:

func main() {
    var counter int

    http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
        if counter%2 == 0 {
            counter++
            writer.Write([]byte(time.Now().String()))
        } else {
            counter++
            writer.WriteHeader(http.StatusInternalServerError)
        }
    })

    err := http.ListenAndServe(":9999", nil)
    if err != nil {
        panic(err)
    }
}

https://golang.org/pkg/net/http/#ResponseWriter

Это хороший ответ, но есть одна маленькая загвоздка. panic вызывает выход из текущей подпрограммы go. http.ListenAndServe запускает несколько подпрограмм go для приема и обработки запросов. Вызов panic приводит к завершению только текущего вызова функции-обработчика. Программа все еще работает и может обрабатывать дальнейшие HTTP-запросы.

mbuechmann 26.10.2018 08:25

Спасибо за указатель @mbuechmann, ответ был обновлен с учетом этого.

Iain Duncan 26.10.2018 08:38

@mbuechmann точен в случае ListenAndServe, но вводит в заблуждение. Обычно panic вызывает завершение вся программа. Однако ListenAndServe оборачивает обработчик каждого запроса в горутину с recover, в частности, чтобы гарантировать, что panic в одном запросе не приведет к отключению всего сервера; но это нет нормальное поведение panic. Нормальное поведение не только останавливает текущую горутину, но и приводит к сбою всего процесса.

Adrian 26.10.2018 15:37

@ Адриан Спасибо. Вы абсолютно правы. Я слишком упростил (из-за незнания).

mbuechmann 26.10.2018 15:58

Другие вопросы по теме