Bubble errors instead of panicking (#194)
This commit is contained in:
@@ -13,22 +13,12 @@ var (
|
||||
callbackReturnSignature = reflect.TypeOf((*error)(nil)).Elem()
|
||||
)
|
||||
|
||||
// Error reported by Kong.
|
||||
type Error struct{ msg string }
|
||||
|
||||
func (e Error) Error() string { return e.msg }
|
||||
|
||||
func fail(format string, args ...interface{}) {
|
||||
panic(Error{msg: fmt.Sprintf(format, args...)})
|
||||
}
|
||||
|
||||
func failField(parent reflect.Value, field reflect.StructField, format string, args ...interface{}) {
|
||||
func failField(parent reflect.Value, field reflect.StructField, format string, args ...interface{}) error {
|
||||
name := parent.Type().Name()
|
||||
if name == "" {
|
||||
name = "<anonymous struct>"
|
||||
}
|
||||
msg := fmt.Sprintf("%s.%s: %s", name, field.Name, fmt.Sprintf(format, args...))
|
||||
panic(Error{msg: msg})
|
||||
return fmt.Errorf("%s.%s: %s", name, field.Name, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// Must creates a new Parser or panics if there is an error.
|
||||
@@ -118,16 +108,22 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||
|
||||
// Synthesise command nodes.
|
||||
for _, dcmd := range k.dynamicCommands {
|
||||
tag := parseTagString(strings.Join(dcmd.tags, " "))
|
||||
tag, terr := parseTagString(strings.Join(dcmd.tags, " "))
|
||||
if terr != nil {
|
||||
return nil, terr
|
||||
}
|
||||
tag.Name = dcmd.name
|
||||
tag.Help = dcmd.help
|
||||
tag.Group = dcmd.group
|
||||
tag.Cmd = true
|
||||
v := reflect.Indirect(reflect.ValueOf(dcmd.cmd))
|
||||
buildChild(k, k.Model.Node, CommandNode, reflect.Value{}, reflect.StructField{
|
||||
err = buildChild(k, k.Model.Node, CommandNode, reflect.Value{}, reflect.StructField{
|
||||
Name: dcmd.name,
|
||||
Type: v.Type(),
|
||||
}, v, tag, dcmd.name, map[string]bool{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, option := range k.postBuildOptions {
|
||||
@@ -231,7 +227,6 @@ func (k *Kong) extraFlags() []*Flag {
|
||||
// Will return a ParseError if a *semantically* invalid command-line is encountered (as opposed to a syntactically
|
||||
// invalid one, which will report a normal error).
|
||||
func (k *Kong) Parse(args []string) (ctx *Context, err error) {
|
||||
defer catch(&err)
|
||||
ctx, err = Trace(k, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -398,12 +393,3 @@ func (k *Kong) LoadConfig(path string) (Resolver, error) {
|
||||
|
||||
return k.loader(r)
|
||||
}
|
||||
|
||||
func catch(err *error) {
|
||||
msg := recover()
|
||||
if test, ok := msg.(Error); ok {
|
||||
*err = test
|
||||
} else if msg != nil {
|
||||
panic(msg)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user