Skip to content

Commit

Permalink
feat: add recover middleware
Browse files Browse the repository at this point in the history
recover middleware wraps other middlewares and recover from panics
  • Loading branch information
aymanbagabas committed Feb 1, 2022
1 parent 0e458e4 commit beb5f0c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
39 changes: 39 additions & 0 deletions recover/recover.go
@@ -0,0 +1,39 @@
package recover

import (
"log"
"runtime/debug"

"github.com/charmbracelet/wish"
"github.com/gliderlabs/ssh"
)

// Middleware is a wish middleware that recovers from panics and log to stderr.
func Middleware(mw ...wish.Middleware) wish.Middleware {
return MiddlewareWithLogger(nil, mw...)
}

// MiddlewareWithLogger is a wish middleware that recovers from panics and log to
// the provided logger.
func MiddlewareWithLogger(logger *log.Logger, mw ...wish.Middleware) wish.Middleware {
if logger == nil {
logger = log.Default()
}
h := func(ssh.Session) {}
for _, m := range mw {
h = m(h)
}
return func(sh ssh.Handler) ssh.Handler {
return func(s ssh.Session) {
func() {
defer func() {
if r := recover(); r != nil {
logger.Printf("panic: %v\n%s", r, string(debug.Stack()))
}
}()
h(s)
}()
sh(s)
}
}
}
35 changes: 35 additions & 0 deletions recover/recover_test.go
@@ -0,0 +1,35 @@
package recover

import (
"testing"

"github.com/charmbracelet/wish/testsession"
"github.com/gliderlabs/ssh"
gossh "golang.org/x/crypto/ssh"
)

func TestMiddleware(t *testing.T) {
t.Run("recover session", func(t *testing.T) {
_, err := setup(t).Output("")
requireNoError(t, err)
})
}

func setup(tb testing.TB) *gossh.Session {
tb.Helper()
return testsession.New(tb, &ssh.Server{
Handler: Middleware(func(h ssh.Handler) ssh.Handler {
return func(s ssh.Session) {
panic("hello")
}
})(func(s ssh.Session) {}),
}, nil)
}

func requireNoError(t *testing.T, err error) {
t.Helper()

if err != nil {
t.Fatalf("expected no error, got %q", err.Error())
}
}

0 comments on commit beb5f0c

Please sign in to comment.