/
recover.go
37 lines (30 loc) · 977 Bytes
/
recover.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package middleware
import (
"log/slog"
"net/http"
"time"
"github.com/getsentry/sentry-go"
"github.com/ainsleydev/webkit/pkg/webkit"
)
// Recover is a middleware that recovers from panics, logs the panic (and a
// backtrace), and returns a HTTP 500 (Internal Server Error) status if
// possible. The error is also reported to Sentry.
//
// This middleware should be plugged in first to ensure that it catches any
// panics that occur in the request-response cycle.
func Recover(next webkit.Handler) webkit.Handler {
return func(ctx *webkit.Context) error {
defer func() {
if err := recover(); err != nil {
sentry.CurrentHub().RecoverWithContext(ctx.Context(), err)
sentry.Flush(time.Second * 5)
slog.ErrorContext(ctx.Context(), "Panic recovered", slog.Any("error", err))
if ctx.Request.Header.Get("Connection") != "Upgrade" {
ctx.Response.WriteHeader(http.StatusInternalServerError)
}
panic(err)
}
}()
return next(ctx)
}
}