错误页面在基于Go的Web应用程序中

huangapple go评论89阅读模式
英文:

Error pages in go based web application

问题

我们正在使用Go构建一个网站,只使用内置的东西,比如http.HandleFunc来设置路由,html.template包来渲染页面。真的没有什么花哨的东西,而且它运行得很好。现在我开始考虑错误处理,并希望能捕获panic等错误并重定向到静态错误页面。使用Go的最佳方法是什么?

我首先考虑的是粗暴的方法,即在检测到错误时直接重定向,但也希望有一个通用的捕获所有错误的方法。我在文档中没有找到相关内容。

(也在考虑类似的404错误处理方法。)

英文:

We are building a web site with go using only the built-in stuff like http.HandleFuncto set up routing and the html.template package to render pages. Nothing fancy really and it works fine. Now I got around to thinking about error handling and would like to catch panics and whatnots and redirect to a static error page. What is the best way to do it with go?

The brute force approach I have been pondering first is to just redirect when an error is detected but it would be nice with a generic catch-all also. I didn't find anything in the docs about it.

(Also thinking about 404s along the same lines.)

答案1

得分: 8

在golang博客上有一篇关于错误处理的很好的文章,它特别涵盖了与Web相关的错误。

http://blog.golang.org/2011/07/error-handling-and-go.html

基本上,你可以用自己的http处理程序包装常规的http处理程序,以便返回错误。包装器会检查你的新处理程序是否返回错误,如果是,则做出相应的反应。我使用类似于这样的代码,我还调用了recover。这是我使用的代码片段(免费且开放)。

虽然我还没有为错误提供自定义页面,但我一直在考虑,应该很容易添加。

// Error是dae.Handler的预期返回,否则为nil。
type Error struct {
Error error
Code int
Message string
}

// NewError是创建Error指针的辅助函数。
func NewError(err error, code int, msg string) *Error {
return &Error{err, code, msg}
}

// Handler用于将函数转换为其类型以实现ServeHTTP。
// 自动恢复并提供服务器500错误的代码。
type Handler func(http.ResponseWriter, *http.Request) *Error

// NewHandler是将多个函数链接在一起的辅助函数。
func New(fn ...Handler) Handler {
if len(fn) == 0 {
panic("未传入处理程序。")
}

h := Handler(fn[0])
for i := 1; i < len(fn); i++ {
    h = h.Add(fn[i])
}
return h

}

// ServeHTTP实现了http.Handler接口。如果appHandler返回错误,则检查错误并写出适当的响应。
func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Printf("%v", r)
http.Error(w, "发生了严重错误。", 500)
if Debug {
panic(r.(error))
}
}
}()

if e := fn(w, r); e != nil {
    log.Printf("Code: %v, Message: \"%s\", Error: %v", e.Code, e.Message, e.Error)
    switch e.Code {
    case 500:
        http.Error(w, e.Message, e.Code)
    case 404:
        http.NotFound(w, r)
        fmt.Fprint(w, e.Message)
    case 200:
        fmt.Fprint(w, e.Message)
    }
}

}

英文:

There's a great write up on the golang blog about error handling and it specifically covers web related errors towards the end.

http://blog.golang.org/2011/07/error-handling-and-go.html

Basically, you wrap the regular http handlers with your own that can return an error. The wrapper checks if your new handlers return an error and if so react. I use something similar to this where i also call recover. Here's a snippet of the code I use (which is free and open).

While I dont yet provide a custom page for errors, it's been on my mind and should be trivial to add.

// Error is the expected return of a dae.Handler, or nil otherwise.
type Error struct {
    Error   error
    Code    int
    Message string
}

// NewError is a helper for creating an Error pointer.
func NewError(err error, code int, msg string) *Error {
    return &amp;Error{err, code, msg}
}

// Handler is used to cast functions to its type to implement ServeHTTP.
// Code that panics is automatically recovered and delivers a server 500 error.
type Handler func(http.ResponseWriter, *http.Request) *Error

// NewHandler is a helper to chain multiple functions together.
func New(fn ...Handler) Handler {
    if len(fn) == 0 {
        panic(&quot;No Handlers passed in.&quot;)
    }

    h := Handler(fn[0])
    for i := 1; i &lt; len(fn); i++ {
        h = h.Add(fn[i])
    }
    return h
}

// ServeHTTP implements the http.Handler interface. If an appHandler returns an
// error, the error is inspected and an appropriate response is written out.
func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    defer func() {
        if r := recover(); r != nil {
            log.Printf(&quot;%v&quot;, r)
            http.Error(w, &quot;A serious error has occured.&quot;, 500)
            if Debug {
                panic(r.(error))
            }
        }
    }()

    if e := fn(w, r); e != nil {
        log.Printf(&quot;Code: %v, Message: \&quot;%s\&quot;, Error: %v&quot;, e.Code, e.Message, e.Error)
        switch e.Code {
        case 500:
            http.Error(w, e.Message, e.Code)
        case 404:
            http.NotFound(w, r)
            fmt.Fprint(w, e.Message)
        case 200:
            fmt.Fprint(w, e.Message)
        }
    }
}

huangapple
  • 本文由 发表于 2012年12月11日 22:46:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/13822150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定