繁体   English   中英

Golang HTTP 自定义错误处理响应

[英]Golang HTTP custom error handling response

我正在浏览https://blog.golang.org/error-handling-and-go ,最后它给出了一个很好的例子,说明如何以更简洁的方式处理返回的错误,并做了一些简单的事情:

// Wrapper for handler functions.
type rootHandler func(http.ResponseWriter, *http.Request) error

// Implement the http.Handler interface.
func (fn rootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    err := fn(w, r) // Call handler function.
    if err == nil {
        return
    }

    ...
}
// POST /api/test/
testRouter.
    Handle("/", rootHandler(create)).
    Methods("POST")

// GET /api/test/{id}/
testRouter.
    HandleFunc("/{id:[0-9]+}/", rootHandler(getByID)).
    Methods("GET")
func create(w http.ResponseWriter, r *http.Request) error {
    // CustomError implementes error
    return &CustomError{
        Kind:       EPARSE,
        Status:     http.StatusBadRequest,
        Message:    "some message",
        Op:         "create",
        Err:        err,
    }
}

这工作得很好,但我宁愿不换行每个控制器方法( create在这种情况下)在rootHandler ,并想出最好的办法是找出某种后的中间件。 我在尝试创建路由器使用的 post-middlewhere 而不是每个控制器方法时失败了,并且想知道您将如何实现这一点。 我能找到的最接近的答案是 emmbee 关于如何将 Go 中间件模式与错误返回请求处理程序结合起来的答案 除了 AuthMiddleware 中的 fn 将是一个控制器方法。

所以理想情况下,我会有下面的处理程序来处理CustomError如果它存在

// POST /api/test
testRouter.
    Handle("/", create).
    Methods("POST")

就上下文而言,我使用的是大猩猩多路复用器和内格罗尼。

任何想法表示赞赏! 非常感谢你。

您的理想解决方案行不通。 mux API 支持http.Handlerfunc(http.ResponseWriter, *http.Request)参数。 你有一个func(http.ResponseWriter, *http.Request) error func(http.ResponseWriter, *http.Request) error不能作为 mux API 支持的参数类型之一传递。

唯一的解决方案是使用rootHandler包装rootHandler每个控制器函数适应 mux API 支持的类型。 与标准的http.HandlerFunc包装器相比,包装器不会增加开销。

使用辅助函数来减少包装器所需的代码量:

func handle(r *mux.Router, p string, fn func(http.ResponseWriter, *http.Request) error) *mux.Route {
    return r.Handle(path, rootHandler(fn))
}

...
handle(testRouter, "/", create).Methods("POST")
handle(testRouter, "/{id:[0-9]+}/", getByID).Methods("GET")

在辅助函数中使用类型开关来处理不同的控制器类型:

func handle(r *mux.Router, p string, h interface{}) *mux.Route {
    switch h := h.(type) {
    case func(http.ResponseWriter, *http.Request) error:
        return r.Handle(p, rootHandler(h))
    case func(http.ResponseWriter, *http.Request):
        return r.HandleFunc(p, h)
    case http.Handler:
        return r.Handle(p, h)
    default:
        panic(fmt.Sprintf("handler type %T not supported", h))
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM