mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-09 20:29:23 +02:00
chore: do not use sentinel errors when unneeded
- main reason being it's a burden to always define sentinel errors at global scope, wrap them with `%w` instead of using a string directly - only use sentinel errors when it has to be checked using `errors.Is` - replace all usage of these sentinel errors in `fmt.Errorf` with direct strings that were in the sentinel error - exclude the sentinel error definition requirement from .golangci.yml - update unit tests to use ContainersError instead of ErrorIs so it stays as a "not a change detector test" without requiring a sentinel error
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/http"
|
||||
@@ -58,8 +57,6 @@ func New(nameTokenPairs []NameToken, client *http.Client) (
|
||||
|
||||
var regexEchoipURL = regexp.MustCompile(`^http(s|):\/\/.+$`)
|
||||
|
||||
var ErrProviderNotValid = errors.New("API name is not valid")
|
||||
|
||||
func ParseProvider(s string) (provider Provider, err error) {
|
||||
possibleProviders := []Provider{
|
||||
Cloudflare,
|
||||
@@ -97,12 +94,10 @@ func ParseProvider(s string) (provider Provider, err error) {
|
||||
providerStrings = append(providerStrings, "a custom "+prefix+" url")
|
||||
}
|
||||
|
||||
return "", fmt.Errorf(`%w: %q can only be %s`,
|
||||
ErrProviderNotValid, s, orStrings(providerStrings))
|
||||
return "", fmt.Errorf("API name is not valid: %q can only be %s",
|
||||
s, orStrings(providerStrings))
|
||||
}
|
||||
|
||||
var ErrCustomURLNotValid = errors.New("custom URL is not valid")
|
||||
|
||||
func checkCustomURL(s, prefix string, regex *regexp.Regexp) (match bool, err error) {
|
||||
if !strings.HasPrefix(s, prefix) {
|
||||
return false, nil
|
||||
@@ -110,15 +105,15 @@ func checkCustomURL(s, prefix string, regex *regexp.Regexp) (match bool, err err
|
||||
s = strings.TrimPrefix(s, prefix)
|
||||
_, err = url.Parse(s)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("%s %w: %w", prefix, ErrCustomURLNotValid, err)
|
||||
return true, fmt.Errorf("%s custom URL is not valid: %w", prefix, err)
|
||||
}
|
||||
|
||||
if regex.MatchString(s) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return true, fmt.Errorf("%s %w: %q does not match regular expression: %s",
|
||||
prefix, ErrCustomURLNotValid, s, regex)
|
||||
return true, fmt.Errorf("%s custom URL is not valid: "+
|
||||
"%q does not match regular expression: %s", prefix, s, regex)
|
||||
}
|
||||
|
||||
func orStrings(strings []string) (result string) {
|
||||
|
||||
@@ -12,17 +12,14 @@ func Test_ParseProvider(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
s string
|
||||
provider Provider
|
||||
errWrapped error
|
||||
errMessage string
|
||||
}{
|
||||
"empty": {
|
||||
errWrapped: ErrProviderNotValid,
|
||||
errMessage: `API name is not valid: "" can only be ` +
|
||||
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
|
||||
},
|
||||
"invalid": {
|
||||
s: "xyz",
|
||||
errWrapped: ErrProviderNotValid,
|
||||
s: "xyz",
|
||||
errMessage: `API name is not valid: "xyz" can only be ` +
|
||||
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
|
||||
},
|
||||
@@ -35,14 +32,12 @@ func Test_ParseProvider(t *testing.T) {
|
||||
provider: IPInfo,
|
||||
},
|
||||
"echoip_url_empty": {
|
||||
s: "echoip#",
|
||||
errWrapped: ErrCustomURLNotValid,
|
||||
s: "echoip#",
|
||||
errMessage: `echoip# custom URL is not valid: "" ` +
|
||||
`does not match regular expression: ^http(s|):\/\/.+$`,
|
||||
},
|
||||
"echoip_url_invalid": {
|
||||
s: "echoip#postgres://localhost:3451",
|
||||
errWrapped: ErrCustomURLNotValid,
|
||||
s: "echoip#postgres://localhost:3451",
|
||||
errMessage: `echoip# custom URL is not valid: "postgres://localhost:3451" ` +
|
||||
`does not match regular expression: ^http(s|):\/\/.+$`,
|
||||
},
|
||||
@@ -59,9 +54,10 @@ func Test_ParseProvider(t *testing.T) {
|
||||
provider, err := ParseProvider(testCase.s)
|
||||
|
||||
assert.Equal(t, testCase.provider, provider)
|
||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||
if testCase.errWrapped != nil {
|
||||
if testCase.errMessage != "" {
|
||||
assert.EqualError(t, err, testCase.errMessage)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ func (c *cloudflare) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
urlBase := "https://speed.cloudflare.com"
|
||||
url := urlBase + "/meta"
|
||||
if ip.IsValid() {
|
||||
return result, fmt.Errorf("%w: cloudflare cannot provide information on the arbitrary IP address %s",
|
||||
ErrServiceLimited, ip)
|
||||
return result, fmt.Errorf("service is limited: "+
|
||||
"cloudflare cannot provide information on the arbitrary IP address %s", ip)
|
||||
}
|
||||
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
@@ -72,8 +72,8 @@ func (c *cloudflare) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrTooManyRequests, url, response.StatusCode, response.Status)
|
||||
default:
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrBadHTTPStatus, url, response.StatusCode, response.Status)
|
||||
return result, fmt.Errorf("bad HTTP status received from %s: %d %s",
|
||||
url, response.StatusCode, response.Status)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
|
||||
@@ -70,11 +70,9 @@ func (e *echoip) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
switch response.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusTooManyRequests:
|
||||
return result, fmt.Errorf("%w from %s: %s",
|
||||
ErrTooManyRequests, url, response.Status)
|
||||
return result, fmt.Errorf("%w from %s: %s", ErrTooManyRequests, url, response.Status)
|
||||
default:
|
||||
return result, fmt.Errorf("%w from %s: %s",
|
||||
ErrBadHTTPStatus, url, response.Status)
|
||||
return result, fmt.Errorf("bad HTTP status received from %s: %s", url, response.Status)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
|
||||
@@ -2,9 +2,4 @@ package api
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrTokenNotValid = errors.New("token is not valid")
|
||||
ErrTooManyRequests = errors.New("too many requests sent for this month")
|
||||
ErrBadHTTPStatus = errors.New("bad HTTP status received")
|
||||
ErrServiceLimited = errors.New("service is limited")
|
||||
)
|
||||
var ErrTooManyRequests = errors.New("too many requests sent for this month")
|
||||
|
||||
@@ -75,7 +75,7 @@ func (i *ip2Location) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
defer response.Body.Close()
|
||||
|
||||
if i.token != "" && response.StatusCode == http.StatusUnauthorized {
|
||||
return result, fmt.Errorf("%w: %s", ErrTokenNotValid, response.Status)
|
||||
return result, fmt.Errorf("token is not valid: %s", response.Status)
|
||||
}
|
||||
|
||||
switch response.StatusCode {
|
||||
@@ -84,8 +84,8 @@ func (i *ip2Location) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrTooManyRequests, url, response.StatusCode, response.Status)
|
||||
default:
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrBadHTTPStatus, url, response.StatusCode, response.Status)
|
||||
return result, fmt.Errorf("bad HTTP status received from %s: %d %s",
|
||||
url, response.StatusCode, response.Status)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
|
||||
@@ -70,7 +70,7 @@ func (i *ipInfo) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
defer response.Body.Close()
|
||||
|
||||
if i.token != "" && response.StatusCode == http.StatusUnauthorized {
|
||||
return result, fmt.Errorf("%w: %s", ErrTokenNotValid, response.Status)
|
||||
return result, fmt.Errorf("token is not valid: %s", response.Status)
|
||||
}
|
||||
|
||||
switch response.StatusCode {
|
||||
@@ -79,8 +79,8 @@ func (i *ipInfo) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrTooManyRequests, url, response.StatusCode, response.Status)
|
||||
default:
|
||||
return result, fmt.Errorf("%w from %s: %d %s",
|
||||
ErrBadHTTPStatus, url, response.StatusCode, response.Status)
|
||||
return result, fmt.Errorf("bad HTTP status received from %s: %d %s",
|
||||
url, response.StatusCode, response.Status)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
|
||||
Reference in New Issue
Block a user