aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-06-06 21:55:37 +0000
committerGravatar Runxi Yu2026-06-06 21:55:37 +0000
commitb08e04bf3f901faf18b3b24672ad313d816b8fb0 (patch)
treeb44ee7f31a4767b994640252c43434b4c3e34a5c
parentref/name, object: Simplify errors (diff)
signatureNo signature
config: Use sentinel errors
-rw-r--r--config/config.go2
-rw-r--r--config/errors.go69
-rw-r--r--config/kind.go65
-rw-r--r--config/lookup.go40
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
}
}