From: aimuz Date: Tue, 20 Feb 2024 02:58:00 +0000 (+0000) Subject: net/netip: introduce parsePrefixError for better error handling X-Git-Tag: go1.23rc1~1128 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=080fc4cf87c4de796b2c5dc14eb9b94f6ec7a35a;p=gostls13.git net/netip: introduce parsePrefixError for better error handling Refactor ParsePrefix to return a parsePrefixError containing the input string and a detailed message on failure, improving error context and maintaining consistent error formatting within the netip package. Change-Id: I8d9fb2f833b0f96f43a14622e66e225b54440410 GitHub-Last-Rev: e17bec3afa4efd6c52463bb93e8f694b42c0c2b7 GitHub-Pull-Request: golang/go#65798 Reviewed-on: https://go-review.googlesource.com/c/go/+/565275 Auto-Submit: Michael Pratt Reviewed-by: Michael Pratt Reviewed-by: Damien Neil LUCI-TryBot-Result: Go LUCI --- diff --git a/src/net/netip/netip.go b/src/net/netip/netip.go index ce498a20fd..7d816b3c64 100644 --- a/src/net/netip/netip.go +++ b/src/net/netip/netip.go @@ -1294,6 +1294,15 @@ func (p Prefix) compare(p2 Prefix) int { return p.Addr().Compare(p2.Addr()) } +type parsePrefixError struct { + in string // the string given to ParsePrefix + msg string // an explanation of the parse failure +} + +func (err parsePrefixError) Error() string { + return "netip.ParsePrefix(" + strconv.Quote(err.in) + "): " + err.msg +} + // ParsePrefix parses s as an IP address prefix. // The string can be in the form "192.168.1.0/24" or "2001:db8::/32", // the CIDR notation defined in RFC 4632 and RFC 4291. @@ -1304,34 +1313,34 @@ func (p Prefix) compare(p2 Prefix) int { func ParsePrefix(s string) (Prefix, error) { i := bytealg.LastIndexByteString(s, '/') if i < 0 { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'") + return Prefix{}, parsePrefixError{in: s, msg: "no '/'"} } ip, err := ParseAddr(s[:i]) if err != nil { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): " + err.Error()) + return Prefix{}, parsePrefixError{in: s, msg: err.Error()} } // IPv6 zones are not allowed: https://go.dev/issue/51899 if ip.Is6() && ip.z != z6noz { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): IPv6 zones cannot be present in a prefix") + return Prefix{}, parsePrefixError{in: s, msg: "IPv6 zones cannot be present in a prefix"} } bitsStr := s[i+1:] // strconv.Atoi accepts a leading sign and leading zeroes, but we don't want that. if len(bitsStr) > 1 && (bitsStr[0] < '1' || bitsStr[0] > '9') { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr)) + return Prefix{}, parsePrefixError{in: s, msg: "bad bits after slash: " + strconv.Quote(bitsStr)} } bits, err := strconv.Atoi(bitsStr) if err != nil { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr)) + return Prefix{}, parsePrefixError{in: s, msg: "bad bits after slash: " + strconv.Quote(bitsStr)} } maxBits := 32 if ip.Is6() { maxBits = 128 } if bits < 0 || bits > maxBits { - return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): prefix length out of range") + return Prefix{}, parsePrefixError{in: s, msg: "prefix length out of range"} } return PrefixFrom(ip, bits), nil }