Skip to content

Commit 096ce41

Browse files
committed
Panic MW: will now return a custom PanicStackError with stack trace when config.DisablePrintStack is set to false.
1 parent 9500f27 commit 096ce41

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

middleware/recover.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (config RecoverConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
7777
if !config.DisablePrintStack {
7878
stack := make([]byte, config.StackSize)
7979
length := runtime.Stack(stack, !config.DisableStackAll)
80-
tmpErr = fmt.Errorf("[PANIC RECOVER] %w %s", tmpErr, stack[:length])
80+
tmpErr = &PanicStackError{Stack: stack[:length], Err: tmpErr}
8181
}
8282
err = tmpErr
8383
}
@@ -86,3 +86,18 @@ func (config RecoverConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
8686
}
8787
}, nil
8888
}
89+
90+
// PanicStackError is an error type that wraps an error along with its stack trace.
91+
// It is returned when config.DisablePrintStack is set to false.
92+
type PanicStackError struct {
93+
Stack []byte
94+
Err error
95+
}
96+
97+
func (e *PanicStackError) Error() string {
98+
return fmt.Sprintf("[PANIC RECOVER] %s %s", e.Err.Error(), e.Stack)
99+
}
100+
101+
func (e *PanicStackError) Unwrap() error {
102+
return e.Err
103+
}

middleware/recover_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package middleware
55

66
import (
77
"bytes"
8+
"errors"
89
"log/slog"
910
"net/http"
1011
"net/http/httptest"
@@ -26,6 +27,14 @@ func TestRecover(t *testing.T) {
2627
})
2728
err := h(c)
2829
assert.Contains(t, err.Error(), "[PANIC RECOVER] test goroutine")
30+
31+
var pse *PanicStackError
32+
if errors.As(err, &pse) {
33+
assert.Contains(t, string(pse.Stack), "middleware/recover.go")
34+
} else {
35+
assert.Fail(t, "not of type PanicStackError")
36+
}
37+
2938
assert.Equal(t, http.StatusOK, rec.Code) // status is still untouched. err is returned from middleware chain
3039
assert.Contains(t, buf.String(), "") // nothing is logged
3140
}

0 commit comments

Comments
 (0)