@jaren
В Go, при возникновении паники (panic), можно обработать ее с помощью механизма "recover". Этот механизм позволяет программисту перехватить панику и выполнить дополнительные действия перед завершением программы.
Чтобы вернуть HTTP-код 500 в случае паники, можно использовать конструкцию defer-recover. Код будет выглядеть примерно так:
1 2 3 4 5 6 7 8 |
func handler(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } }() // код вашего обработчика здесь } |
Этот код перехватывает любые паники, которые могут возникнуть внутри обработчика, и возвращает HTTP-код 500 вместе с сообщением об ошибке. Вы можете настроить сообщение об ошибке на свое усмотрение.
Также, для удобства, можно создать отдельную функцию для обработки ошибок и использовать ее в своих обработчиках:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func handleError(w http.ResponseWriter, err error) { log.Println(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } func handler(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { handleError(w, fmt.Errorf("panic: %v", err)) } }() // код вашего обработчика здесь } |
В этом примере мы создаем отдельную функцию handleError, которая логирует ошибку и возвращает HTTP-код 500. Обработчик handler использует эту функцию для обработки ошибок, которые могут возникнуть внутри него.
@jaren
Логика обработки паники может отличаться в зависимости от требований вашего приложения или фреймворка, которым вы пользуетесь. Однако, всякий раз при возникновении паники вы можете вызывать функцию-обработчик и передавать в нее объект ResponseWriter и панику. Далее вы можете использовать методы ResponseWriter для отправки интересующего вас HTTP-кода и сообщения об ошибке.
Ниже приведен пример кода, используя стандартный пакет net/http:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } func handler(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { log.Println("panic occurred:", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } }() // код вашего обработчика здесь // Пример паники для тестирования panic("Something went wrong") } |
В этом примере мы регистрируем обработчик "/" для корневого пути и запускаем сервер на порту 8080. Обработчик имеет структуру, аналогичную предыдущему примеру. Внутри блока defer
есть проверка на панику. Если паника возникла, мы логируем ее и отправляем HTTP-код 500 и сообщение "Internal Server Error". Помимо этого, вы можете выполнять другие операции, такие как сохранение стека вызовов и отправка уведомлений о панике на почту или другие каналы связи, в зависимости от требований вашего приложения.
Обратите внимание, что использование recover() в других функциях отличных от handler() не позволит перехватить панику, поэтому рекомендуется использовать этот механизм в самом обработчике или централизованно в middleware, если вы используете фреймворк.