Focus on catching fewer panics in HandleAction

so that "unknown" panics can still bubble up.
This commit is contained in:
Dan Buch 2016-06-09 17:32:00 -04:00
parent 7817f72540
commit 5a3515fdf8
No known key found for this signature in database
GPG Key ID: FAEF12936DD3E3EC
2 changed files with 21 additions and 5 deletions

13
app.go
View File

@ -8,6 +8,7 @@ import (
"path/filepath"
"reflect"
"sort"
"strings"
"time"
)
@ -464,11 +465,13 @@ func (a Author) String() string {
func HandleAction(action interface{}, context *Context) (err error) {
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case error:
err = r.(error)
default:
err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2)
// Try to detect a known reflection error from *this scope*, rather than
// swallowing all panics that may happen when calling an Action func.
s := fmt.Sprintf("%v", r)
if strings.HasPrefix(s, "reflect: ") && strings.Contains(s, "too many input arguments") {
err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2)
} else {
panic(r)
}
}
}()

View File

@ -1452,3 +1452,16 @@ func TestHandleAction_WithInvalidFuncReturnSignature(t *testing.T) {
t.Fatalf("expected error exit code to be 2, but got: %v", exitErr.ExitCode())
}
}
func TestHandleAction_WithUnknownPanic(t *testing.T) {
defer func() { refute(t, recover(), nil) }()
var fn ActionFunc
app := NewApp()
app.Action = func(ctx *Context) error {
fn(ctx)
return nil
}
HandleAction(app.Action, NewContext(app, flagSet(app.Name, app.Flags), nil))
}