bugsnag-go
bugsnag-go copied to clipboard
Example with go-chi
Anyone?
Hi @josemarluedke, thanks for requesting this. I've made a note internally to confirm support for chi and if so to put together an example project. It could be some time until we get around to it as we have lots of higher priority things to do at the moment. Thanks for your patience!
Any news on this?
I think it's unlikely we will get to it any time in the near future as we are working on other things at the moment. Sorry I can't be more helpful right now!
As go-chi is just a router, you can very easily get it up and running with yourrouter.Use(bugsnag.Handler) like in the example:
package main
import (
"net/http"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := chi.NewRouter()
r.Use(bugsnag.Handler) // <- here, make sure it's the first one on the chain
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
})
http.ListenAndServe(":3333", r)
}
Note that you can't use chi's provided middleware.Recoverer as it will bury errors and prevent Bugsnag from capturing them.
Edit
Default middleware only captures panics, but not errors that are returned to the user. Wrote a quick middlware, that captures panics and http errors >404:
note: since the error is created in the middleware itself, the stacktrace will always be the same. I plan to attach errors to the context and get them out in the defer statement.
package server
import (
"fmt"
"net/http"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/go-chi/chi/v5/middleware"
)
func ErrorHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
request := r
ctx := bugsnag.StartSession(r.Context())
defer bugsnag.AutoNotify(ctx) // capture panics
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
defer func() {
status := ww.Status()
if status > 404 { // capture http errors
bugsnag.Notify(fmt.Errorf("%s %s returned %d", r.Method, r.URL, status), request)
}
}()
next.ServeHTTP(ww, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
Just panics:
I needed to wrap the handler (it was taking an extra variable). This worked for me:
package main
import (
"net/http"
"github.com/bugsnag/bugsnag-go/v2"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := chi.NewRouter()
r.Use(func(next http.Handler) http.Handler { return bugsnag.Handler(next) }) // <- here, make sure it's the first one on the chain
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
})
http.ListenAndServe(":3333", r)
}