diff options
| author | 2026-06-06 21:55:37 +0000 | |
|---|---|---|
| committer | 2026-06-06 21:55:37 +0000 | |
| commit | b08e04bf3f901faf18b3b24672ad313d816b8fb0 (patch) | |
| tree | b44ee7f31a4767b994640252c43434b4c3e34a5c | |
| parent | ref/name, object: Simplify errors (diff) | |
| signature | No signature | |
config: Use sentinel errors
| -rw-r--r-- | config/config.go | 2 | ||||
| -rw-r--r-- | config/errors.go | 69 | ||||
| -rw-r--r-- | config/kind.go | 65 | ||||
| -rw-r--r-- | config/lookup.go | 40 |
4 files changed, 60 insertions, 116 deletions
diff --git a/config/config.go b/config/config.go index 4252659f..35e0ea09 100644 --- a/config/config.go +++ b/config/config.go @@ -140,6 +140,6 @@ func (p *configParser) parse() (*Config, error) { func (p *configParser) parseError(reason string) error { return &ParseError{ Line: p.lineNum, - Reason: reason, + reason: reason, } } diff --git a/config/errors.go b/config/errors.go index b1049b34..a26bb3cb 100644 --- a/config/errors.go +++ b/config/errors.go @@ -1,56 +1,39 @@ package config -import "fmt" +import ( + "errors" + "fmt" +) -// ParseError describes a syntactic error in Git config input. -type ParseError struct { - Line int - Reason string -} +var ( + // ErrMissing indicates that a looked-up key does not exist. + ErrMissing = errors.New("config: key not found") -func (err *ParseError) Error() string { - if err.Line > 0 { - return fmt.Sprintf("config: parse line %d: %s", err.Line, err.Reason) - } + // ErrValueless indicates that a key exists but carries no value. + ErrValueless = errors.New("config: key has no value") - return "config: parse: " + err.Reason -} + // ErrValueEmpty indicates an empty value where one was required. + ErrValueEmpty = errors.New("config: empty value") -// LookupError describes an invalid lookup result conversion. -type LookupError struct { - Kind Kind - Operation string -} + // ErrValueRange indicates a value outside the representable range. + ErrValueRange = errors.New("config: value out of range") -func (err *LookupError) Error() string { - switch err.Kind { - case KindMissing: - return fmt.Sprintf("config: %s: missing config value", err.Operation) - case KindValueless: - return fmt.Sprintf("config: %s: valueless config key", err.Operation) - case KindString: - return fmt.Sprintf("config: %s: invalid string config value", err.Operation) - default: - return fmt.Sprintf("config: %s: unknown value kind %d", err.Operation, err.Kind) - } -} + // ErrValueSyntax indicates a malformed value. + ErrValueSyntax = errors.New("config: invalid value syntax") +) + +// ParseError describes a syntactic error in Git config input. +type ParseError struct { + // Line is the 1-based input line where the error was detected. + Line int -// ValueError describes a typed value conversion failure. -type ValueError struct { - Operation string - Value string - Reason string - Err error + reason string } -func (err *ValueError) Error() string { - if err.Err != nil { - return fmt.Sprintf("config: %s %q: %s: %v", err.Operation, err.Value, err.Reason, err.Err) +func (err *ParseError) Error() string { + if err.Line > 0 { + return fmt.Sprintf("config: parse line %d: %s", err.Line, err.reason) } - return fmt.Sprintf("config: %s %q: %s", err.Operation, err.Value, err.Reason) -} - -func (err *ValueError) Unwrap() error { - return err.Err + return "config: parse: " + err.reason } diff --git a/config/kind.go b/config/kind.go index 07870c9e..cf87a348 100644 --- a/config/kind.go +++ b/config/kind.go @@ -1,6 +1,7 @@ package config import ( + "fmt" "math" "strconv" "strings" @@ -56,38 +57,28 @@ func parseBool(value string) (bool, error) { n, err := parseInt32(value) if err != nil { - return false, &ValueError{ - Operation: "parse bool", - Value: value, - Reason: "invalid boolean value", - Err: err, - } + return false, err } return n != 0, nil } func parseInt32(value string) (int32, error) { - n64, err := parseInt64WithMax(value, math.MaxInt32, "parse int32") + n64, err := parseInt64WithMax(value, math.MaxInt32) if err != nil { return 0, err } n32, err := intconv.Int64ToInt32(n64) if err != nil { - return 0, &ValueError{ - Operation: "parse int32", - Value: value, - Reason: "convert integer", - Err: err, - } + return 0, fmt.Errorf("%w: %q", ErrValueRange, value) } return n32, nil } func parseInt(value string) (int, error) { - n64, err := parseInt64WithMax(value, int64(int(^uint(0)>>1)), "parse int") + n64, err := parseInt64WithMax(value, int64(int(^uint(0)>>1))) if err != nil { return 0, err } @@ -96,27 +87,17 @@ func parseInt(value string) (int, error) { } func parseInt64(value string) (int64, error) { - return parseInt64WithMax(value, int64(^uint64(0)>>1), "parse int64") + return parseInt64WithMax(value, int64(^uint64(0)>>1)) } -func parseInt64WithMax(value string, maxValue int64, operation string) (int64, error) { +func parseInt64WithMax(value string, maxValue int64) (int64, error) { if value == "" { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "empty value", - Err: nil, - } + return 0, ErrValueEmpty } trimmed := strings.TrimLeft(value, " \t\n\r\f\v") if trimmed == "" { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "empty value", - Err: nil, - } + return 0, fmt.Errorf("%w: %q", ErrValueEmpty, value) } numPart := trimmed @@ -136,43 +117,23 @@ func parseInt64WithMax(value string, maxValue int64, operation string) (int64, e } if numPart == "" { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "missing integer value", - Err: nil, - } + return 0, fmt.Errorf("%w: %q", ErrValueSyntax, value) } n, err := strconv.ParseInt(numPart, 0, 64) if err != nil { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "parse integer", - Err: err, - } + return 0, fmt.Errorf("%w: %q: %w", ErrValueSyntax, value, err) } intMax := maxValue intMin := -maxValue - 1 if n > 0 && n > intMax/factor { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "integer overflow", - Err: nil, - } + return 0, fmt.Errorf("%w: %q", ErrValueRange, value) } if n < 0 && n < intMin/factor { - return 0, &ValueError{ - Operation: operation, - Value: value, - Reason: "integer overflow", - Err: nil, - } + return 0, fmt.Errorf("%w: %q", ErrValueRange, value) } n *= factor diff --git a/config/lookup.go b/config/lookup.go index ede22700..ede2026e 100644 --- a/config/lookup.go +++ b/config/lookup.go @@ -13,56 +13,56 @@ type LookupResult struct { // String returns the explicit string value. func (r LookupResult) String() (string, error) { switch r.Kind { - case KindMissing: - return "", &LookupError{Kind: r.Kind, Operation: "string"} - case KindValueless: - return "", &LookupError{Kind: r.Kind, Operation: "string"} case KindString: return r.Value, nil + case KindValueless: + return "", ErrValueless + case KindMissing: + return "", ErrMissing default: - return "", &LookupError{Kind: r.Kind, Operation: "string"} + return "", ErrMissing } } // Bool interprets this lookup result using Git config boolean rules. func (r LookupResult) Bool() (bool, error) { switch r.Kind { - case KindMissing: - return false, &LookupError{Kind: r.Kind, Operation: "bool"} - case KindValueless: - return true, nil case KindString: return parseBool(r.Value) + case KindValueless: + return true, nil + case KindMissing: + return false, ErrMissing default: - return false, &LookupError{Kind: r.Kind, Operation: "bool"} + return false, ErrMissing } } // Int interprets this lookup result as a Git integer value. func (r LookupResult) Int() (int, error) { switch r.Kind { - case KindMissing: - return 0, &LookupError{Kind: r.Kind, Operation: "int"} - case KindValueless: - return 0, &LookupError{Kind: r.Kind, Operation: "int"} case KindString: return parseInt(r.Value) + case KindValueless: + return 0, ErrValueless + case KindMissing: + return 0, ErrMissing default: - return 0, &LookupError{Kind: r.Kind, Operation: "int"} + return 0, ErrMissing } } // Int64 interprets this lookup result as a Git int64 value. func (r LookupResult) Int64() (int64, error) { switch r.Kind { - case KindMissing: - return 0, &LookupError{Kind: r.Kind, Operation: "int64"} - case KindValueless: - return 0, &LookupError{Kind: r.Kind, Operation: "int64"} case KindString: return parseInt64(r.Value) + case KindValueless: + return 0, ErrValueless + case KindMissing: + return 0, ErrMissing default: - return 0, &LookupError{Kind: r.Kind, Operation: "int64"} + return 0, ErrMissing } } |
