golang ブログにはエラー処理に関するすばらしい記事があり、特に Web 関連のエラーを最後に取り上げています。
http://blog.golang.org/2011/07/error-handling-and-go.html
基本的に、通常の http ハンドラーを、エラーを返す独自のハンドラーでラップします。ラッパーは、新しいハンドラーがエラーを返すかどうかをチェックし、そうであれば反応します。これに似たものを使用して、recover とも呼びます。これは私が使用するコードのスニペットです (これは無料でオープンです)。
エラー用のカスタム ページはまだ用意していませんが、気になっているので簡単に追加できるはずです。
// 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 &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("No Handlers passed in.")
}
h := Handler(fn[0])
for i := 1; i < 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("%v", r)
http.Error(w, "A serious error has occured.", 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)
}
}
}