0

RecoverWrapマティーニルートのすべてのハンドラーに配線して、panic内部のコードですべてを終了させたいと考えていますRecoverWrap

私はそれをやろうとしましたm.Use(RecoverWrap)が、正確に行う方法がわかりません。コンパイルに失敗します。

package main

import (
    "errors"
    "github.com/go-martini/martini"
    "net/http"
)

func main() {
    m := martini.Classic()
    //m.Use(RecoverWrap)
    m.Get("/", func() {
        panic("some panic")
    })

    m.Run()
}

func RecoverWrap(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
        var err error
        defer func() {
            r := recover()
            if r != nil {
                switch t := r.(type) {
                case string:
                    err = errors.New(t)
                case error:
                    err = t
                default:
                    err = errors.New("Unknown error")
                }

                http.Error(w, "Something goes wrong", http.StatusInternalServerError)
            }
        }()
        h.ServeHTTP(w, req)
    })
}
4

1 に答える 1

1

Martini のミドルウェア ハンドラーは他のハンドラー呼び出しを「ラップ」できないため、インジェクターは http.Handler を見つけられません。

できることは、context.Next()を使用することです:

package main

import (
"errors"
"github.com/go-martini/martini"
"net/http"
)

func main() {
    m := martini.Classic()
    m.Use(RecoverWrap)
    m.Get("/", func() {
        panic("some panic")
        })

    m.Run()
}

func RecoverWrap(c martini.Context, w http.ResponseWriter) {
    var err error
    defer func(w http.ResponseWriter) {
        r := recover()
        if r != nil {
            switch t := r.(type) {
            case string:
                err = errors.New(t)
            case error:
                err = t
            default:
                err = errors.New("Unknown error")
            }
            http.Error(w, "Something goes wrong", http.StatusInternalServerError)
        }
        }(w)
    c.Next()
}

エラー ハンドラーが最初に登録されたミドルウェアであることを確認する必要があります。そうしないと、以前に実行されていたハンドラーがキャッチされません。

実際、同じメソッドがmartini.Recoveryに実装されています。

https://github.com/go-martini/martini/blob/6241001738f6e1b1ea7c4a4089195e1b0681609a/recovery.go#L115

于 2015-02-28T15:54:32.647 に答える