gpt4 book ai didi

Go Gorilla panic 处理程序以自定义状态响应

转载 作者:IT王子 更新时间:2023-10-29 02:29:55 30 4
gpt4 key购买 nike

在 gorilla 中,使用 RecoveryHandler我们可以抑制 panic 。然而,对于给定的错误类型,是否有一个处理程序或库方法来响应特定的 Http 状态代码和消息。
例如,如果发生 Mandatory field missing error 的 Panic,人们会希望用 Http 400 和一条有意义的消息来说明负载到底出了什么问题。< br/>

执行此操作的推荐方法是什么?
更新在代码中:列出了 2 种方法

  1. 处理每次方法调用时返回的错误并构建响应。
  2. 不是返回错误,而是使用自定义错误类型 panic 并将错误恢复推迟到函数来构建响应。这使代码易于阅读并减少重复。
func fooHandler(w http.ResponseWriter, r *http.Request) {
//decode the request body into a struct instance
if err := decode(r, myInstance); err != nil {
sendErrorResponse(w,err,http.StatusBadRequest)
return
}
//validate the struct instance for all mandatory keys presence
if err := file.validate(); err != nil {
sendErrorResponse(w,err,http.StatusBadRequest)
return
}
//call DB and validate the response and handle the error

//do some computation and again handle error.

//finally construct response
}

func barHandler(w http.ResponseWriter, r *http.Request) {
//similar to above handler many funcs are called before the response is contruscted
}

func tomHandler(w http.ResponseWriter, r *http.Request) {
//similar to above handler many funcs are called before the response is contruscted
}

func differentHandler(w http.ResponseWriter, r *http.Request) {
defer recoverForErrors(w,r)
// call as many funcs as you need.
// validation, decoding etc will panic instead of returning errors.
// This will avoid the repetitive boiler plate code of handling error and converting to meaningful error response
// instead all this logic is pushed to recoverForErrors func. Which retrieves the error from panic and checks for
// specific error type to construct the error http response
}

最佳答案

尽可能依赖标准库提供的接口(interface)是惯用的。在这种情况下,来自 net/httphttp.Handler 接口(interface)包。

在您的情况下,您可以创建一个新类型,允许您的处理程序返回错误类型,并集中处理所有这些错误情况。

// StatusError wraps an existing error with a HTTP status code.
type StatusError struct {
Status int
// Allows you to wrap another error
Err error
}

func (e *StatusError) Error() string {
return e.Error()
}

type AppHandler func(w http.ResponseWriter, r *http.Request) error

// Satisfies the http.Handler interface
func (ah AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Centralises your error handling
err := ah(w, r)
if err != nil {
switch e := a.(type) {
case *StatusError:
switch e.Status {
case 400:
http.Error(w, e.Err.Error(), 400)
return
case 404:
http.NotFound(w, r)
return
default:
http.Error(w, http.StatusText(500), 500)
return
}
default:
http.Error(w, http.StatusText(500), 500)
return
}
}

// Your handlers will look like this
func SomeHandler(w http.ResponseWriter, r *http.Request) error {
err := decode(r, myInstance)
if err != nil {
return &StatusError{400, err}
}

err := file.validate()
if err != nil {
return &StatusError{400, err}
}

// Continue on...
return nil
}

您在这里获得的好处包括:

  • 不要为可以处理的错误而 panic
  • 您可以将错误处理集中在您的 ServeHTTP 方法中 - 即对于 400 错误,您可以将错误原因写入响应。对于 500 错误,您可能会返回一条通用消息,因为 HTTP 500 不是用户可以解决的问题。
  • 您的处理函数显式返回错误,您不再需要记住使用裸return 语句来避免继续执行。
  • 您的 StatusError 类型用状态代码包装错误,但仍然允许您轻松检查/记录/写出包装的错误。

进一步阅读:

关于Go Gorilla panic 处理程序以自定义状态响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33904503/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com