raven-go icon indicating copy to clipboard operation
raven-go copied to clipboard

net/http: raven.RecoveryHandler cannot be passed into mux.Handle

Open linusthe3rd opened this issue 9 years ago • 3 comments

If I create a new HTTP handler like so:

fooHandler, err := handlers.NewFooHandler()
if err != nil {
    log.Fatalf("Error: %s", err)
}

mux := http.NewServeMux()
mux.Handle("/foo/", raven.RecoveryHandler(fooHandler))

I get the following two exceptions:

cannot use fooHandler (type *handlers.SnsBounceHandler) as type func(http.ResponseWriter, *http.Request) in argument to raven.RecoveryHandler

cannot use raven.RecoveryHandler(snsBh) (type func(http.ResponseWriter, *http.Request)) as type http.Handler in argument to mux.Handle:
    func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method)

It looks like two things are occurring here:

  1. Custom objects that implement the http.Handler interface are not accepted in the raven.RecoveryHandler function.
  2. One cannot use the raven.RecoverHandler function with mux.Handle because RecoveryHandler returns a function handler instead of a http.Handle object.

linusthe3rd avatar Apr 20 '16 17:04 linusthe3rd

Yeah, so RecoveryHandler expects a HandlerFunc not http.Handle. We can probably just add another function that works with http.Handle.

Ideally, we'd swap the API to be: raven.RecoverHandlerFunc and raven.RecoverHandler.

Would you like to submit a PR for this?

I'm also not sure the best way to go about actually making this API change since versions don't really exist.

mattrobenolt avatar Apr 20 '16 18:04 mattrobenolt

This was the first thing I ran into when integrating raven-go. The library works great, but that usage definitely doesn't match idiomatic go handlers. I've submitted a PR. If you are worried about breaking changes, you could use something like gopkg.in for versioning.

@strife25 it's not the prettiest solution, but you can get pretty close with the existing implementation by using http.HanderFunc:

fooHandler = http.HandlerFunc(raven.RecoveryHandler(fooHandler.ServeHTTP))
mux.Handle("/foo/", fooHandler)

I suggest wrapping your entire mux, so all handlers get the benefit of reporting. I do something like the following: (handlers.LoggingHandler is from http://www.gorillatoolkit.org/pkg/handlers)

    mux := http.NewServeMux()
    mux.Handle("/foo/", fooHandler)
    mux.Handle("/bar/", barHandler)
    // ... other handlers ...

    handler := http.HandlerFunc(raven.RecoveryHandler(mux.ServeHTTP))
    handler = handlers.LoggingHandler(os.Stdout, handler)
    http.ListenAndServe(addr, handler)

tdterry avatar Sep 13 '16 19:09 tdterry

mux.Use(raven.Recovery) looks to now be available as of https://github.com/getsentry/raven-go/pull/193

jacque006 avatar Dec 13 '18 02:12 jacque006