微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Golang HTTP 自定义错误处理响应

如何解决Golang HTTP 自定义错误处理响应

我正在经历 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 在 How can I combine Go middleware pattern with error returning request handlers? 上的答案,除了 AuthMiddleware 中的 fn 是控制器方法

因此,理想情况下,我将使用以下处理程序来处理 CustomError(如果存在)

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

就上下文而言,我使用的是 gorilla mux 和 negroni。

任何想法都值得赞赏!非常感谢。

解决方法

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

唯一的解决方案是使用 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,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))
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?