Clean up error handling a bit.
This commit is contained in:
@@ -688,3 +688,12 @@ func TestParentBindings(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "foo", cli.Command.value)
|
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)`)
|
||||||
|
}
|
||||||
|
|||||||
@@ -271,7 +271,12 @@ func (v *Value) IsBool() bool {
|
|||||||
func (v *Value) Parse(scan *Scanner, target reflect.Value) error {
|
func (v *Value) Parse(scan *Scanner, target reflect.Value) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
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)
|
err := v.Mapper.Decode(&DecodeContext{Value: v, Scan: scan}, target)
|
||||||
|
|||||||
+33
-3
@@ -5,8 +5,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate stringer -type=TokenType
|
|
||||||
|
|
||||||
// TokenType is the type of a token.
|
// TokenType is the type of a token.
|
||||||
type TokenType int
|
type TokenType int
|
||||||
|
|
||||||
@@ -21,6 +19,26 @@ const (
|
|||||||
PositionalArgumentToken // <arg>
|
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.
|
// Token created by Scanner.
|
||||||
type Token struct {
|
type Token struct {
|
||||||
Value string
|
Value string
|
||||||
@@ -58,6 +76,18 @@ func (t Token) IsAny(types ...TokenType) bool {
|
|||||||
return false
|
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.
|
// 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.
|
// 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 {
|
func (s *Scanner) PopValue(context string) string {
|
||||||
t := s.Pop()
|
t := s.Pop()
|
||||||
if !t.IsValue() {
|
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
|
return t.Value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user