2012-12-11 15 views
5

http.HandleFuncなどの組み込みのものだけを使用してルーティングを設定し、html.templateパッケージをレンダリングするWebサイトを構築しています。本当に素晴らしいことは何もなく、うまく動作します。今、私はエラー処理について考える程度だとパニックとwhatnotsをキャッチし、静的エラーページにリダイレクトしたいと思います。 goと一緒にそれをする最善の方法は何ですか?goベースのWebアプリケーションのエラーページ

私が最初に熟考されているブルートフォースアプローチは、エラーが検出されたときにだけリダイレクトすることですが、それはまた、一般的なキャッチオールといいだろう。私はそれについてのドキュメントで何も見つかりませんでした。

(また同じラインに沿って404エラーについて考える。)

答えて

8

ありエラー処理についてgolangのブログに大きな書き込みアップだし、それを具体的に終わりに向かってウェブ関連のエラーをカバーしています。

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

基本的には、エラーを返すことができ、あなた自身の持つ通常のHTTPハンドラを包みます。ラッパーチェックし、あなたの新しいハンドラがエラーを返した場合とそう反応した場合。私はリカバリを呼び出す場所に似た何かを使用します。ここで(フリーかつオープンである)私が使用したコードの抜粋です。

私はエラーのカスタムページを提供し、まだいけないが、それは私の心にされていますし、追加するのは簡単でなければなりません。

// 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) 
     } 
    } 
} 
関連する問題