Merge pull request #452 from urfave/handle-action-undiaper

Focus on catching fewer panics in HandleAction
This commit is contained in:
Dan Buch 2016-06-10 11:00:26 -04:00 committed by GitHub
commit e5bef42c62
2 changed files with 21 additions and 5 deletions

11
app.go
View File

@ -8,6 +8,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"sort" "sort"
"strings"
"time" "time"
) )
@ -464,11 +465,13 @@ func (a Author) String() string {
func HandleAction(action interface{}, context *Context) (err error) { func HandleAction(action interface{}, context *Context) (err error) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
switch r.(type) { // Try to detect a known reflection error from *this scope*, rather than
case error: // swallowing all panics that may happen when calling an Action func.
err = r.(error) s := fmt.Sprintf("%v", r)
default: 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) 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()) 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))
}