Clean up error handling a bit.

This commit is contained in:
Alec Thomas
2018-11-03 09:49:00 +11:00
parent c0df056b14
commit fddfb973d6
4 changed files with 48 additions and 20 deletions
+9
View File
@@ -688,3 +688,12 @@ func TestParentBindings(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "foo", cli.Command.value)
}
func TestNumericParamErrors(t *testing.T) {
var cli struct {
Name string
}
parser := mustNew(t, &cli)
_, err := parser.Parse([]string{"--name", "-10"})
require.EqualError(t, err, `expected string value but got "-10" (short flag)`)
}
+6 -1
View File
@@ -271,7 +271,12 @@ func (v *Value) IsBool() bool {
func (v *Value) Parse(scan *Scanner, target reflect.Value) error {
defer func() {
if err := recover(); err != nil {
panic(fmt.Sprintf("mapper %T failed to apply to %s: %s", v.Mapper, v.Summary(), err))
switch err := err.(type) {
case Error:
panic(err)
default:
panic(fmt.Sprintf("mapper %T failed to apply to %s: %s", v.Mapper, v.Summary(), err))
}
}
}()
err := v.Mapper.Decode(&DecodeContext{Value: v, Scan: scan}, target)
+33 -3
View File
@@ -5,8 +5,6 @@ import (
"strings"
)
//go:generate stringer -type=TokenType
// TokenType is the type of a token.
type TokenType int
@@ -21,6 +19,26 @@ const (
PositionalArgumentToken // <arg>
)
func (t TokenType) String() string {
switch t {
case UntypedToken:
return "untyped"
case EOLToken:
return "<EOL>"
case FlagToken: // --<flag>
return "long flag"
case FlagValueToken: // =<value>
return "flag value"
case ShortFlagToken: // -<short>[<tail]
return "short flag"
case ShortFlagTailToken: // <tail>
return "short flag remainder"
case PositionalArgumentToken: // <arg>
return "positional argument"
}
panic("unsupported type")
}
// Token created by Scanner.
type Token struct {
Value string
@@ -58,6 +76,18 @@ func (t Token) IsAny(types ...TokenType) bool {
return false
}
// InferredType tries to infer the type of a token.
func (t Token) InferredType() TokenType {
if t.Type == UntypedToken {
if strings.HasPrefix(t.Value, "--") {
return FlagToken
} else if strings.HasPrefix(t.Value, "-") {
return ShortFlagToken
}
}
return t.Type
}
// IsValue returns true if token is usable as a parseable value.
//
// A parseable value is either a value typed token, or an untyped token NOT starting with a hyphen.
@@ -113,7 +143,7 @@ func (s *Scanner) Pop() Token {
func (s *Scanner) PopValue(context string) string {
t := s.Pop()
if !t.IsValue() {
fail("expected %s value but got %s", context, t)
fail("expected %s value but got %s (%s)", context, t, t.InferredType())
}
return t.Value
}
-16
View File
@@ -1,16 +0,0 @@
// Code generated by "stringer -type=TokenType"; DO NOT EDIT.
package kong
import "strconv"
const _TokenType_name = "UntypedTokenEOLTokenFlagTokenFlagValueTokenShortFlagTokenShortFlagTailTokenPositionalArgumentToken"
var _TokenType_index = [...]uint8{0, 12, 20, 29, 43, 57, 75, 98}
func (i TokenType) String() string {
if i < 0 || i >= TokenType(len(_TokenType_index)-1) {
return "TokenType(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _TokenType_name[_TokenType_index[i]:_TokenType_index[i+1]]
}