Merge pull request #3620 from mmorel-35/errors

use Go standard errors
This commit is contained in:
Ben Kochie 2023-12-08 17:18:24 +01:00 committed by GitHub
commit 4a0bf2aa74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 184 additions and 170 deletions

View File

@ -1,8 +1,8 @@
run:
deadline: 5m
skip-files:
# Skip autogenerated files.
- ^.*\.(pb|y)\.go$
timeout: 5m
output:
sort-results: true
@ -10,12 +10,15 @@ output:
linters:
enable:
- depguard
- errorlint
- gofumpt
- goimports
- revive
- misspell
issues:
max-issues-per-linter: 0
max-same-issues: 0
exclude-rules:
- path: _test.go
linters:
@ -32,6 +35,8 @@ linters-settings:
desc: "Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert"
- pkg: github.com/go-kit/kit/log
desc: "Use github.com/go-kit/log instead of github.com/go-kit/kit/log"
- pkg: github.com/pkg/errors
desc: "Use errors or fmt instead of github.com/pkg/errors"
errcheck:
exclude-functions:
# Don't flag lines such as "io.Copy(io.Discard, resp.Body)".

View File

@ -100,7 +100,7 @@ func (o Options) validate() error {
// call is also needed to get the APIs into an operational state.
func New(opts Options) (*API, error) {
if err := opts.validate(); err != nil {
return nil, fmt.Errorf("invalid API options: %s", err)
return nil, fmt.Errorf("invalid API options: %w", err)
}
l := opts.Logger
if l == nil {

View File

@ -14,6 +14,7 @@
package v2
import (
"errors"
"fmt"
"net/http"
"regexp"
@ -635,7 +636,7 @@ func (api *API) deleteSilenceHandler(params silence_ops.DeleteSilenceParams) mid
sid := params.SilenceID.String()
if err := api.silences.Expire(sid); err != nil {
level.Error(logger).Log("msg", "Failed to expire silence", "err", err)
if err == silence.ErrNotFound {
if errors.Is(err, silence.ErrNotFound) {
return silence_ops.NewDeleteSilenceNotFound()
}
return silence_ops.NewDeleteSilenceInternalServerError().WithPayload(err.Error())
@ -669,7 +670,7 @@ func (api *API) postSilencesHandler(params silence_ops.PostSilencesParams) middl
sid, err := api.silences.Set(sil)
if err != nil {
level.Error(logger).Log("msg", "Failed to create silence", "err", err)
if err == silence.ErrNotFound {
if errors.Is(err, silence.ErrNotFound) {
return silence_ops.NewPostSilencesNotFound().WithPayload(err.Error())
}
return silence_ops.NewPostSilencesBadRequest().WithPayload(err.Error())

View File

@ -16,12 +16,12 @@ package cli
import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"sync"
kingpin "github.com/alecthomas/kingpin/v2"
"github.com/pkg/errors"
"github.com/prometheus/alertmanager/api/v2/client/silence"
"github.com/prometheus/alertmanager/api/v2/models"
@ -62,7 +62,8 @@ func addSilenceWorker(ctx context.Context, sclient silence.ClientService, silenc
sid := s.ID
params := silence.NewPostSilencesParams().WithContext(ctx).WithSilence(s)
postOk, err := sclient.PostSilences(params)
if _, ok := err.(*silence.PostSilencesNotFound); ok {
var e *silence.PostSilencesNotFound
if errors.As(err, &e) {
// silence doesn't exists yet, retry to create as a new one
params.Silence.ID = ""
postOk, err = sclient.PostSilences(params)
@ -92,7 +93,7 @@ func (c *silenceImportCmd) bulkImport(ctx context.Context, _ *kingpin.ParseConte
// read open square bracket
_, err = dec.Token()
if err != nil {
return errors.Wrap(err, "couldn't unmarshal input data, is it JSON?")
return fmt.Errorf("couldn't unmarshal input data, is it JSON?: %w", err)
}
amclient := NewAlertmanagerClient(alertmanagerURL)
@ -121,7 +122,7 @@ func (c *silenceImportCmd) bulkImport(ctx context.Context, _ *kingpin.ParseConte
var s models.PostableSilence
err := dec.Decode(&s)
if err != nil {
return errors.Wrap(err, "couldn't unmarshal input data, is it JSON?")
return fmt.Errorf("couldn't unmarshal input data, is it JSON?: %w", err)
}
if c.force {

View File

@ -154,7 +154,7 @@ func (c *silenceQueryCmd) query(ctx context.Context, _ *kingpin.ParseContext) er
return errors.New("unknown output formatter")
}
if err := formatter.FormatSilences(displaySilences); err != nil {
return fmt.Errorf("error formatting silences: %v", err)
return fmt.Errorf("error formatting silences: %w", err)
}
}
return nil

View File

@ -131,7 +131,7 @@ func (c *silenceUpdateCmd) update(ctx context.Context, _ *kingpin.ParseContext)
return fmt.Errorf("unknown output formatter")
}
if err := formatter.FormatSilences(updatedSilences); err != nil {
return fmt.Errorf("error formatting silences: %v", err)
return fmt.Errorf("error formatting silences: %w", err)
}
}
return nil

View File

@ -14,10 +14,11 @@
package cluster
import (
"errors"
"fmt"
"net"
"github.com/hashicorp/go-sockaddr"
"github.com/pkg/errors"
)
type getIPFunc func() (string, error)
@ -38,7 +39,7 @@ func calculateAdvertiseAddress(bindAddr, advertiseAddr string, allowInsecureAdve
if advertiseAddr != "" {
ip := net.ParseIP(advertiseAddr)
if ip == nil {
return nil, errors.Errorf("failed to parse advertise addr '%s'", advertiseAddr)
return nil, fmt.Errorf("failed to parse advertise addr '%s'", advertiseAddr)
}
if ip4 := ip.To4(); ip4 != nil {
ip = ip4
@ -52,7 +53,7 @@ func calculateAdvertiseAddress(bindAddr, advertiseAddr string, allowInsecureAdve
ip := net.ParseIP(bindAddr)
if ip == nil {
return nil, errors.Errorf("failed to parse bind addr '%s'", bindAddr)
return nil, fmt.Errorf("failed to parse bind addr '%s'", bindAddr)
}
return ip, nil
}
@ -64,7 +65,7 @@ func calculateAdvertiseAddress(bindAddr, advertiseAddr string, allowInsecureAdve
func discoverAdvertiseAddress(allowInsecureAdvertise bool) (net.IP, error) {
addr, err := getPrivateAddress()
if err != nil {
return nil, errors.Wrap(err, "failed to get private IP")
return nil, fmt.Errorf("failed to get private IP: %w", err)
}
if addr == "" && !allowInsecureAdvertise {
return nil, errors.New("no private IP found, explicit advertise addr not provided")
@ -73,7 +74,7 @@ func discoverAdvertiseAddress(allowInsecureAdvertise bool) (net.IP, error) {
if addr == "" {
addr, err = getPublicAddress()
if err != nil {
return nil, errors.Wrap(err, "failed to get public IP")
return nil, fmt.Errorf("failed to get public IP: %w", err)
}
if addr == "" {
return nil, errors.New("no private/public IP found, explicit advertise addr not provided")
@ -82,7 +83,7 @@ func discoverAdvertiseAddress(allowInsecureAdvertise bool) (net.IP, error) {
ip := net.ParseIP(addr)
if ip == nil {
return nil, errors.Errorf("failed to parse discovered IP '%s'", addr)
return nil, fmt.Errorf("failed to parse discovered IP '%s'", addr)
}
return ip, nil
}

View File

@ -15,6 +15,7 @@ package cluster
import (
"context"
"errors"
"fmt"
"math/rand"
"net"
@ -28,7 +29,6 @@ import (
"github.com/go-kit/log/level"
"github.com/hashicorp/memberlist"
"github.com/oklog/ulid"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
)
@ -146,11 +146,11 @@ func Create(
) (*Peer, error) {
bindHost, bindPortStr, err := net.SplitHostPort(bindAddr)
if err != nil {
return nil, errors.Wrap(err, "invalid listen address")
return nil, fmt.Errorf("invalid listen address: %w", err)
}
bindPort, err := strconv.Atoi(bindPortStr)
if err != nil {
return nil, errors.Wrapf(err, "address %s: invalid port", bindAddr)
return nil, fmt.Errorf("address %s: invalid port: %w", bindAddr, err)
}
var advertiseHost string
@ -159,17 +159,17 @@ func Create(
var advertisePortStr string
advertiseHost, advertisePortStr, err = net.SplitHostPort(advertiseAddr)
if err != nil {
return nil, errors.Wrap(err, "invalid advertise address")
return nil, fmt.Errorf("invalid advertise address: %w", err)
}
advertisePort, err = strconv.Atoi(advertisePortStr)
if err != nil {
return nil, errors.Wrapf(err, "address %s: invalid port", advertiseAddr)
return nil, fmt.Errorf("address %s: invalid port: %w", advertiseAddr, err)
}
}
resolvedPeers, err := resolvePeers(context.Background(), knownPeers, advertiseAddr, &net.Resolver{}, waitIfEmpty)
if err != nil {
return nil, errors.Wrap(err, "resolve peers")
return nil, fmt.Errorf("resolve peers: %w", err)
}
level.Debug(l).Log("msg", "resolved peers to following addresses", "peers", strings.Join(resolvedPeers, ","))
@ -242,13 +242,13 @@ func Create(
level.Info(l).Log("msg", "using TLS for gossip")
cfg.Transport, err = NewTLSTransport(context.Background(), l, reg, cfg.BindAddr, cfg.BindPort, tlsTransportConfig)
if err != nil {
return nil, errors.Wrap(err, "tls transport")
return nil, fmt.Errorf("tls transport: %w", err)
}
}
ml, err := memberlist.Create(cfg)
if err != nil {
return nil, errors.Wrap(err, "create memberlist")
return nil, fmt.Errorf("create memberlist: %w", err)
}
p.mlist = ml
return p, nil
@ -736,7 +736,7 @@ func resolvePeers(ctx context.Context, peers []string, myAddress string, res *ne
for _, peer := range peers {
host, port, err := net.SplitHostPort(peer)
if err != nil {
return nil, errors.Wrapf(err, "split host/port for peer %s", peer)
return nil, fmt.Errorf("split host/port for peer %s: %w", peer, err)
}
retryCtx, cancel := context.WithCancel(ctx)
@ -761,7 +761,7 @@ func resolvePeers(ctx context.Context, peers []string, myAddress string, res *ne
ips, err = res.LookupIPAddr(retryCtx, host)
if err != nil {
lookupErrSpotted = true
return errors.Wrapf(err, "IP Addr lookup for peer %s", peer)
return fmt.Errorf("IP Addr lookup for peer %s: %w", peer, err)
}
ips = removeMyAddr(ips, port, myAddress)

View File

@ -15,12 +15,12 @@ package cluster
import (
"crypto/tls"
"errors"
"fmt"
"sync"
"time"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/pkg/errors"
)
const capacity = 1024
@ -38,7 +38,7 @@ func newConnectionPool(tlsClientCfg *tls.Config) (*connectionPool, error) {
},
)
if err != nil {
return nil, errors.Wrap(err, "failed to create new LRU")
return nil, fmt.Errorf("failed to create new LRU: %w", err)
}
return &connectionPool{
cache: cache,

View File

@ -17,6 +17,8 @@ import (
"bufio"
"crypto/tls"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
"sync"
@ -24,7 +26,6 @@ import (
"github.com/gogo/protobuf/proto"
"github.com/hashicorp/memberlist"
"github.com/pkg/errors"
"github.com/prometheus/alertmanager/cluster/clusterpb"
)
@ -99,7 +100,7 @@ func (conn *tlsConn) writePacket(fromAddr string, b []byte) error {
},
)
if err != nil {
return errors.Wrap(err, "unable to marshal memeberlist packet message")
return fmt.Errorf("unable to marshal memeberlist packet message: %w", err)
}
buf := make([]byte, uint32length, uint32length+len(msg))
binary.LittleEndian.PutUint32(buf, uint32(len(msg)))
@ -116,7 +117,7 @@ func (conn *tlsConn) writeStream() error {
},
)
if err != nil {
return errors.Wrap(err, "unable to marshal memeberlist stream message")
return fmt.Errorf("unable to marshal memeberlist stream message: %w", err)
}
buf := make([]byte, uint32length, uint32length+len(msg))
binary.LittleEndian.PutUint32(buf, uint32(len(msg)))
@ -136,7 +137,7 @@ func (conn *tlsConn) read() (*memberlist.Packet, error) {
lenBuf := make([]byte, uint32length)
_, err := io.ReadFull(reader, lenBuf)
if err != nil {
return nil, errors.Wrap(err, "error reading message length")
return nil, fmt.Errorf("error reading message length: %w", err)
}
msgLen := binary.LittleEndian.Uint32(lenBuf)
msgBuf := make([]byte, msgLen)
@ -144,12 +145,12 @@ func (conn *tlsConn) read() (*memberlist.Packet, error) {
conn.mtx.Unlock()
if err != nil {
return nil, errors.Wrap(err, "error reading message")
return nil, fmt.Errorf("error reading message: %w", err)
}
pb := clusterpb.MemberlistMessage{}
err = proto.Unmarshal(msgBuf, &pb)
if err != nil {
return nil, errors.Wrap(err, "error parsing message")
return nil, fmt.Errorf("error parsing message: %w", err)
}
if pb.Version != version {
return nil, errors.New("tls memberlist message version incompatible")
@ -167,7 +168,7 @@ func (conn *tlsConn) read() (*memberlist.Packet, error) {
func toPacket(pb clusterpb.MemberlistMessage) (*memberlist.Packet, error) {
addr, err := net.ResolveTCPAddr(network, pb.FromAddr)
if err != nil {
return nil, errors.Wrap(err, "error parsing packet sender address")
return nil, fmt.Errorf("error parsing packet sender address: %w", err)
}
return &memberlist.Packet{
Buf: pb.Msg,

View File

@ -20,6 +20,7 @@ package cluster
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"strings"
@ -29,7 +30,6 @@ import (
"github.com/go-kit/log/level"
"github.com/hashicorp/go-sockaddr"
"github.com/hashicorp/memberlist"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
common "github.com/prometheus/common/config"
"github.com/prometheus/exporter-toolkit/web"
@ -83,12 +83,12 @@ func NewTLSTransport(
tlsServerCfg, err := web.ConfigToTLSConfig(cfg.TLSServerConfig)
if err != nil {
return nil, errors.Wrap(err, "invalid TLS server config")
return nil, fmt.Errorf("invalid TLS server config: %w", err)
}
tlsClientCfg, err := common.NewTLSConfig(cfg.TLSClientConfig)
if err != nil {
return nil, errors.Wrap(err, "invalid TLS client config")
return nil, fmt.Errorf("invalid TLS client config: %w", err)
}
ip := net.ParseIP(bindAddr)
@ -99,12 +99,12 @@ func NewTLSTransport(
addr := &net.TCPAddr{IP: ip, Port: bindPort}
listener, err := tls.Listen(network, addr.String(), tlsServerCfg)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("failed to start TLS listener on %q port %d", bindAddr, bindPort))
return nil, fmt.Errorf("failed to start TLS listener on %q port %d: %w", bindAddr, bindPort, err)
}
connPool, err := newConnectionPool(tlsClientCfg)
if err != nil {
return nil, errors.Wrap(err, "failed to initialize tls transport connection pool")
return nil, fmt.Errorf("failed to initialize tls transport connection pool: %w", err)
}
ctx, cancel := context.WithCancel(ctx)
@ -155,7 +155,7 @@ func (t *TLSTransport) FinalAdvertiseAddr(ip string, port int) (net.IP, int, err
var err error
ip, err = sockaddr.GetPrivateIP()
if err != nil {
return nil, 0, fmt.Errorf("failed to get interface addresses: %v", err)
return nil, 0, fmt.Errorf("failed to get interface addresses: %w", err)
}
if ip == "" {
return nil, 0, fmt.Errorf("no private IP address found, and explicit IP not provided")
@ -203,13 +203,13 @@ func (t *TLSTransport) WriteTo(b []byte, addr string) (time.Time, error) {
conn, err := t.connPool.borrowConnection(addr, DefaultTCPTimeout)
if err != nil {
t.writeErrs.WithLabelValues("packet").Inc()
return time.Now(), errors.Wrap(err, "failed to dial")
return time.Now(), fmt.Errorf("failed to dial: %w", err)
}
fromAddr := t.listener.Addr().String()
err = conn.writePacket(fromAddr, b)
if err != nil {
t.writeErrs.WithLabelValues("packet").Inc()
return time.Now(), errors.Wrap(err, "failed to write packet")
return time.Now(), fmt.Errorf("failed to write packet: %w", err)
}
t.packetsSent.Add(float64(len(b)))
return time.Now(), nil
@ -221,13 +221,13 @@ func (t *TLSTransport) DialTimeout(addr string, timeout time.Duration) (net.Conn
conn, err := dialTLSConn(addr, timeout, t.tlsClientCfg)
if err != nil {
t.writeErrs.WithLabelValues("stream").Inc()
return nil, errors.Wrap(err, "failed to dial")
return nil, fmt.Errorf("failed to dial: %w", err)
}
err = conn.writeStream()
netConn := conn.getRawConn()
if err != nil {
t.writeErrs.WithLabelValues("stream").Inc()
return netConn, errors.Wrap(err, "failed to create stream connection")
return netConn, fmt.Errorf("failed to create stream connection: %w", err)
}
t.streamsSent.Inc()
return netConn, nil

View File

@ -15,6 +15,7 @@ package main
import (
"context"
"errors"
"fmt"
"net"
"net/http"
@ -31,7 +32,6 @@ import (
"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/model"
@ -332,7 +332,7 @@ func run() int {
GroupFunc: groupFn,
})
if err != nil {
level.Error(logger).Log("err", errors.Wrap(err, "failed to create API"))
level.Error(logger).Log("err", fmt.Errorf("failed to create API: %w", err))
return 1
}
@ -370,7 +370,7 @@ func run() int {
configCoordinator.Subscribe(func(conf *config.Config) error {
tmpl, err = template.FromGlobs(conf.Templates)
if err != nil {
return errors.Wrap(err, "failed to parse templates")
return fmt.Errorf("failed to parse templates: %w", err)
}
tmpl.ExternalURL = amURL
@ -508,7 +508,7 @@ func run() int {
srvc := make(chan struct{})
go func() {
if err := web.ListenAndServe(srv, webConfig, logger); err != http.ErrServerClosed {
if err := web.ListenAndServe(srv, webConfig, logger); !errors.Is(err, http.ErrServerClosed) {
level.Error(logger).Log("msg", "Listen error", "err", err)
close(srvc)
}
@ -572,7 +572,7 @@ func extURL(logger log.Logger, hostnamef func() (string, error), listen, externa
return nil, err
}
if u.Scheme != "http" && u.Scheme != "https" {
return nil, errors.Errorf("%q: invalid %q scheme, only 'http' and 'https' are supported", u.String(), u.Scheme)
return nil, fmt.Errorf("%q: invalid %q scheme, only 'http' and 'https' are supported", u.String(), u.Scheme)
}
ppref := strings.TrimRight(u.Path, "/")

View File

@ -15,6 +15,7 @@ package config
import (
"encoding/json"
"errors"
"fmt"
"net"
"net/url"
@ -25,7 +26,6 @@ import (
"strings"
"time"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"gopkg.in/yaml.v2"
@ -689,7 +689,7 @@ func (hp *HostPort) UnmarshalYAML(unmarshal func(interface{}) error) error {
return err
}
if hp.Port == "" {
return errors.Errorf("address %q: port cannot be empty", s)
return fmt.Errorf("address %q: port cannot be empty", s)
}
return nil
}
@ -711,7 +711,7 @@ func (hp *HostPort) UnmarshalJSON(data []byte) error {
return err
}
if hp.Port == "" {
return errors.Errorf("address %q: port cannot be empty", s)
return fmt.Errorf("address %q: port cannot be empty", s)
}
return nil
}

View File

@ -21,7 +21,6 @@ import (
"text/template"
"time"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/sigv4"
)
@ -541,7 +540,7 @@ func (c *WechatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
if !wechatTypeMatcher.MatchString(c.MessageType) {
return errors.Errorf("weChat message type %q does not match valid options %s", c.MessageType, wechatValidTypesRe)
return fmt.Errorf("weChat message type %q does not match valid options %s", c.MessageType, wechatValidTypesRe)
}
return nil
@ -587,18 +586,18 @@ func (c *OpsGenieConfig) UnmarshalYAML(unmarshal func(interface{}) error) error
for _, r := range c.Responders {
if r.ID == "" && r.Username == "" && r.Name == "" {
return errors.Errorf("opsGenieConfig responder %v has to have at least one of id, username or name specified", r)
return fmt.Errorf("opsGenieConfig responder %v has to have at least one of id, username or name specified", r)
}
if strings.Contains(r.Type, "{{") {
_, err := template.New("").Parse(r.Type)
if err != nil {
return errors.Errorf("opsGenieConfig responder %v type is not a valid template: %v", r, err)
return fmt.Errorf("opsGenieConfig responder %v type is not a valid template: %w", r, err)
}
} else {
r.Type = strings.ToLower(r.Type)
if !opsgenieTypeMatcher.MatchString(r.Type) {
return errors.Errorf("opsGenieConfig responder %v type does not match valid options %s", r, opsgenieValidTypesRe)
return fmt.Errorf("opsGenieConfig responder %v type does not match valid options %s", r, opsgenieValidTypesRe)
}
}
}

View File

@ -15,6 +15,7 @@ package dispatch
import (
"context"
"errors"
"fmt"
"sort"
"sync"
@ -343,7 +344,7 @@ func (d *Dispatcher) processAlert(alert *types.Alert, route *Route) {
_, _, err := d.stage.Exec(ctx, d.logger, alerts...)
if err != nil {
lvl := level.Error(d.logger)
if ctx.Err() == context.Canceled {
if errors.Is(ctx.Err(), context.Canceled) {
// It is expected for the context to be canceled on
// configuration reload or shutdown. In this case, the
// message should only be logged at the debug level.

1
go.mod
View File

@ -28,7 +28,6 @@ require (
github.com/matttproud/golang_protobuf_extensions v1.0.4
github.com/oklog/run v1.1.0
github.com/oklog/ulid v1.3.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/common v0.45.0
github.com/prometheus/common/assets v0.2.0

1
go.sum
View File

@ -466,7 +466,6 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

View File

@ -132,7 +132,7 @@ func (p *parser) parseCloseBrace(l *lexer) (parseFunc, error) {
if p.hasOpenBrace {
// If there was an open brace there must be a matching close brace.
if _, err := p.expect(l, tokenCloseBrace); err != nil {
return nil, fmt.Errorf("0:%d: %s: %w", l.position().columnEnd, err, errNoCloseBrace)
return nil, fmt.Errorf("0:%d: %w: %w", l.position().columnEnd, err, errNoCloseBrace)
}
} else {
// If there was no open brace there must not be a close brace either.
@ -152,7 +152,7 @@ func (p *parser) parseMatcher(l *lexer) (parseFunc, error) {
)
// The first token should be the label name.
if t, err = p.expect(l, tokenQuoted, tokenUnquoted); err != nil {
return nil, fmt.Errorf("%s: %w", err, errNoLabelName)
return nil, fmt.Errorf("%w: %w", err, errNoLabelName)
}
matchName, err = t.unquote()
if err != nil {
@ -160,7 +160,7 @@ func (p *parser) parseMatcher(l *lexer) (parseFunc, error) {
}
// The next token should be the operator.
if t, err = p.expect(l, tokenEquals, tokenNotEquals, tokenMatches, tokenNotMatches); err != nil {
return nil, fmt.Errorf("%s: %w", err, errNoOperator)
return nil, fmt.Errorf("%w: %w", err, errNoOperator)
}
switch t.kind {
case tokenEquals:
@ -177,7 +177,7 @@ func (p *parser) parseMatcher(l *lexer) (parseFunc, error) {
// The next token should be the match value. Like the match name, this too
// can be either double-quoted UTF-8 or unquoted UTF-8 without reserved characters.
if t, err = p.expect(l, tokenUnquoted, tokenQuoted); err != nil {
return nil, fmt.Errorf("%s: %w", err, errNoLabelValue)
return nil, fmt.Errorf("%w: %w", err, errNoLabelValue)
}
matchValue, err = t.unquote()
if err != nil {
@ -185,7 +185,7 @@ func (p *parser) parseMatcher(l *lexer) (parseFunc, error) {
}
m, err := labels.NewMatcher(matchTy, matchName, matchValue)
if err != nil {
return nil, fmt.Errorf("failed to create matcher: %s", err)
return nil, fmt.Errorf("failed to create matcher: %w", err)
}
p.matchers = append(p.matchers, m)
return p.parseEndOfMatcher, nil
@ -199,7 +199,7 @@ func (p *parser) parseEndOfMatcher(l *lexer) (parseFunc, error) {
// open brace has a matching close brace
return p.parseCloseBrace, nil
}
return nil, fmt.Errorf("%s: %w", err, errExpectedCommaOrCloseBrace)
return nil, fmt.Errorf("%w: %w", err, errExpectedCommaOrCloseBrace)
}
switch t.kind {
case tokenComma:
@ -213,7 +213,7 @@ func (p *parser) parseEndOfMatcher(l *lexer) (parseFunc, error) {
func (p *parser) parseComma(l *lexer) (parseFunc, error) {
if _, err := p.expect(l, tokenComma); err != nil {
return nil, fmt.Errorf("%s: %w", err, errExpectedComma)
return nil, fmt.Errorf("%w: %w", err, errExpectedComma)
}
// The token after the comma can be another matcher, a close brace or end of input.
t, err := p.expectPeek(l, tokenCloseBrace, tokenUnquoted, tokenQuoted)
@ -223,7 +223,7 @@ func (p *parser) parseComma(l *lexer) (parseFunc, error) {
// open brace has a matching close brace
return p.parseCloseBrace, nil
}
return nil, fmt.Errorf("%s: %w", err, errExpectedMatcherOrCloseBrace)
return nil, fmt.Errorf("%w: %w", err, errExpectedMatcherOrCloseBrace)
}
if t.kind == tokenCloseBrace {
return p.parseCloseBrace, nil
@ -234,7 +234,7 @@ func (p *parser) parseComma(l *lexer) (parseFunc, error) {
func (p *parser) parseEOF(l *lexer) (parseFunc, error) {
t, err := l.scan()
if err != nil {
return nil, fmt.Errorf("%s: %w", err, errExpectedEOF)
return nil, fmt.Errorf("%w: %w", err, errExpectedEOF)
}
if !t.isEOF() {
return nil, fmt.Errorf("%d:%d: %s: %w", t.columnStart, t.columnEnd, t.value, errExpectedEOF)

View File

@ -212,7 +212,7 @@ func decodeState(r io.Reader) (state, error) {
st[stateKey(string(e.Entry.GroupKey), e.Entry.Receiver)] = &e
continue
}
if err == io.EOF {
if errors.Is(err, io.EOF) {
break
}
return nil, err

View File

@ -17,6 +17,7 @@ import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"math/rand"
"mime"
@ -32,7 +33,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
@ -133,7 +133,7 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
if n.conf.Smarthost.Port == "465" {
tlsConfig, err := commoncfg.NewTLSConfig(&n.conf.TLSConfig)
if err != nil {
return false, errors.Wrap(err, "parse TLS configuration")
return false, fmt.Errorf("parse TLS configuration: %w", err)
}
if tlsConfig.ServerName == "" {
tlsConfig.ServerName = n.conf.Smarthost.Host
@ -141,7 +141,7 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
conn, err = tls.Dial("tcp", n.conf.Smarthost.String(), tlsConfig)
if err != nil {
return true, errors.Wrap(err, "establish TLS connection to server")
return true, fmt.Errorf("establish TLS connection to server: %w", err)
}
} else {
var (
@ -150,13 +150,13 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
)
conn, err = d.DialContext(ctx, "tcp", n.conf.Smarthost.String())
if err != nil {
return true, errors.Wrap(err, "establish connection to server")
return true, fmt.Errorf("establish connection to server: %w", err)
}
}
c, err = smtp.NewClient(conn, n.conf.Smarthost.Host)
if err != nil {
conn.Close()
return true, errors.Wrap(err, "create SMTP client")
return true, fmt.Errorf("create SMTP client: %w", err)
}
defer func() {
// Try to clean up after ourselves but don't log anything if something has failed.
@ -168,37 +168,37 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
if n.conf.Hello != "" {
err = c.Hello(n.conf.Hello)
if err != nil {
return true, errors.Wrap(err, "send EHLO command")
return true, fmt.Errorf("send EHLO command: %w", err)
}
}
// Global Config guarantees RequireTLS is not nil.
if *n.conf.RequireTLS {
if ok, _ := c.Extension("STARTTLS"); !ok {
return true, errors.Errorf("'require_tls' is true (default) but %q does not advertise the STARTTLS extension", n.conf.Smarthost)
return true, fmt.Errorf("'require_tls' is true (default) but %q does not advertise the STARTTLS extension", n.conf.Smarthost)
}
tlsConf, err := commoncfg.NewTLSConfig(&n.conf.TLSConfig)
if err != nil {
return false, errors.Wrap(err, "parse TLS configuration")
return false, fmt.Errorf("parse TLS configuration: %w", err)
}
if tlsConf.ServerName == "" {
tlsConf.ServerName = n.conf.Smarthost.Host
}
if err := c.StartTLS(tlsConf); err != nil {
return true, errors.Wrap(err, "send STARTTLS command")
return true, fmt.Errorf("send STARTTLS command: %w", err)
}
}
if ok, mech := c.Extension("AUTH"); ok {
auth, err := n.auth(mech)
if err != nil {
return true, errors.Wrap(err, "find auth mechanism")
return true, fmt.Errorf("find auth mechanism: %w", err)
}
if auth != nil {
if err := c.Auth(auth); err != nil {
return true, errors.Wrapf(err, "%T auth", auth)
return true, fmt.Errorf("%T auth: %w", auth, err)
}
}
}
@ -210,37 +210,37 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
)
from := tmpl(n.conf.From)
if tmplErr != nil {
return false, errors.Wrap(tmplErr, "execute 'from' template")
return false, fmt.Errorf("execute 'from' template: %w", tmplErr)
}
to := tmpl(n.conf.To)
if tmplErr != nil {
return false, errors.Wrap(tmplErr, "execute 'to' template")
return false, fmt.Errorf("execute 'to' template: %w", tmplErr)
}
addrs, err := mail.ParseAddressList(from)
if err != nil {
return false, errors.Wrap(err, "parse 'from' addresses")
return false, fmt.Errorf("parse 'from' addresses: %w", err)
}
if len(addrs) != 1 {
return false, errors.Errorf("must be exactly one 'from' address (got: %d)", len(addrs))
return false, fmt.Errorf("must be exactly one 'from' address (got: %d)", len(addrs))
}
if err = c.Mail(addrs[0].Address); err != nil {
return true, errors.Wrap(err, "send MAIL command")
return true, fmt.Errorf("send MAIL command: %w", err)
}
addrs, err = mail.ParseAddressList(to)
if err != nil {
return false, errors.Wrapf(err, "parse 'to' addresses")
return false, fmt.Errorf("parse 'to' addresses: %w", err)
}
for _, addr := range addrs {
if err = c.Rcpt(addr.Address); err != nil {
return true, errors.Wrapf(err, "send RCPT command")
return true, fmt.Errorf("send RCPT command: %w", err)
}
}
// Send the email headers and body.
message, err := c.Data()
if err != nil {
return true, errors.Wrapf(err, "send DATA command")
return true, fmt.Errorf("send DATA command: %w", err)
}
defer message.Close()
@ -248,7 +248,7 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
for header, t := range n.conf.Headers {
value, err := n.tmpl.ExecuteTextString(t, data)
if err != nil {
return false, errors.Wrapf(err, "execute %q header template", header)
return false, fmt.Errorf("execute %q header template: %w", header, err)
}
fmt.Fprintf(buffer, "%s: %s\r\n", header, mime.QEncoding.Encode("utf-8", value))
}
@ -268,7 +268,7 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
// and active/resolved.
_, err = message.Write(buffer.Bytes())
if err != nil {
return false, errors.Wrap(err, "write headers")
return false, fmt.Errorf("write headers: %w", err)
}
if len(n.conf.Text) > 0 {
@ -278,20 +278,20 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
"Content-Type": {"text/plain; charset=UTF-8"},
})
if err != nil {
return false, errors.Wrap(err, "create part for text template")
return false, fmt.Errorf("create part for text template: %w", err)
}
body, err := n.tmpl.ExecuteTextString(n.conf.Text, data)
if err != nil {
return false, errors.Wrap(err, "execute text template")
return false, fmt.Errorf("execute text template: %w", err)
}
qw := quotedprintable.NewWriter(w)
_, err = qw.Write([]byte(body))
if err != nil {
return true, errors.Wrap(err, "write text part")
return true, fmt.Errorf("write text part: %w", err)
}
err = qw.Close()
if err != nil {
return true, errors.Wrap(err, "close text part")
return true, fmt.Errorf("close text part: %w", err)
}
}
@ -304,31 +304,31 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
"Content-Type": {"text/html; charset=UTF-8"},
})
if err != nil {
return false, errors.Wrap(err, "create part for html template")
return false, fmt.Errorf("create part for html template: %w", err)
}
body, err := n.tmpl.ExecuteHTMLString(n.conf.HTML, data)
if err != nil {
return false, errors.Wrap(err, "execute html template")
return false, fmt.Errorf("execute html template: %w", err)
}
qw := quotedprintable.NewWriter(w)
_, err = qw.Write([]byte(body))
if err != nil {
return true, errors.Wrap(err, "write HTML part")
return true, fmt.Errorf("write HTML part: %w", err)
}
err = qw.Close()
if err != nil {
return true, errors.Wrap(err, "close HTML part")
return true, fmt.Errorf("close HTML part: %w", err)
}
}
err = multipartWriter.Close()
if err != nil {
return false, errors.Wrap(err, "close multipartWriter")
return false, fmt.Errorf("close multipartWriter: %w", err)
}
_, err = message.Write(multipartBuffer.Bytes())
if err != nil {
return false, errors.Wrap(err, "write body buffer")
return false, fmt.Errorf("write body buffer: %w", err)
}
success = true

View File

@ -16,6 +16,7 @@ package msteams
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -185,8 +186,8 @@ func TestNotifier_Notify_WithReason(t *testing.T) {
if tt.noError {
require.NoError(t, err)
} else {
reasonError, ok := err.(*notify.ErrorWithReason)
require.True(t, ok)
var reasonError *notify.ErrorWithReason
require.True(t, errors.As(err, &reasonError))
require.Equal(t, tt.expectedReason, reasonError.Reason)
}
})

View File

@ -15,6 +15,7 @@ package notify
import (
"context"
"errors"
"fmt"
"sort"
"sync"
@ -24,7 +25,6 @@ import (
"github.com/cespare/xxhash/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
@ -686,7 +686,7 @@ func (n *DedupStage) Exec(ctx context.Context, _ log.Logger, alerts ...*types.Al
ctx = WithResolvedAlerts(ctx, resolved)
entries, err := n.nflog.Query(nflog.QGroupKey(gkey), nflog.QReceiver(n.recv))
if err != nil && err != nflog.ErrNotFound {
if err != nil && !errors.Is(err, nflog.ErrNotFound) {
return ctx, nil, err
}
@ -696,7 +696,7 @@ func (n *DedupStage) Exec(ctx context.Context, _ log.Logger, alerts ...*types.Al
case 1:
entry = entries[0]
default:
return ctx, nil, errors.Errorf("unexpected entry result size %d", len(entries))
return ctx, nil, fmt.Errorf("unexpected entry result size %d", len(entries))
}
if n.needsUpdate(entry, firingSet, resolvedSet, repeatInterval) {
@ -736,7 +736,8 @@ func (r RetryStage) Exec(ctx context.Context, l log.Logger, alerts ...*types.Ale
failureReason := DefaultReason.String()
if err != nil {
if e, ok := errors.Cause(err).(*ErrorWithReason); ok {
var e *ErrorWithReason
if errors.As(err, &e) {
failureReason = e.Reason.String()
}
r.metrics.numTotalFailedNotifications.WithLabelValues(append(r.labelValues, failureReason)...).Inc()
@ -797,7 +798,10 @@ func (r RetryStage) exec(ctx context.Context, l log.Logger, alerts ...*types.Ale
}
}
return ctx, nil, errors.Wrapf(iErr, "%s/%s: notify retry canceled after %d attempts", r.groupName, r.integration.String(), i)
if iErr != nil {
return ctx, nil, fmt.Errorf("%s/%s: notify retry canceled after %d attempts: %w", r.groupName, r.integration.String(), i, iErr)
}
return ctx, nil, nil
default:
}
@ -811,7 +815,7 @@ func (r RetryStage) exec(ctx context.Context, l log.Logger, alerts ...*types.Ale
if err != nil {
r.metrics.numNotificationRequestsFailedTotal.WithLabelValues(r.labelValues...).Inc()
if !retry {
return ctx, alerts, errors.Wrapf(err, "%s/%s: notify retry canceled due to unrecoverable error after %d attempts", r.groupName, r.integration.String(), i)
return ctx, alerts, fmt.Errorf("%s/%s: notify retry canceled due to unrecoverable error after %d attempts: %w", r.groupName, r.integration.String(), i, err)
}
if ctx.Err() == nil {
if iErr == nil || err.Error() != iErr.Error() {
@ -840,8 +844,10 @@ func (r RetryStage) exec(ctx context.Context, l log.Logger, alerts ...*types.Ale
iErr = NewErrorWithReason(ContextDeadlineExceededReason, iErr)
}
}
return ctx, nil, errors.Wrapf(iErr, "%s/%s: notify retry canceled after %d attempts", r.groupName, r.integration.String(), i)
if iErr != nil {
return ctx, nil, fmt.Errorf("%s/%s: notify retry canceled after %d attempts: %w", r.groupName, r.integration.String(), i, iErr)
}
return ctx, nil, nil
}
}
}

View File

@ -24,7 +24,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
@ -281,13 +280,13 @@ func (n *Notifier) createRequests(ctx context.Context, as ...*types.Alert) ([]*h
} else {
content, err := os.ReadFile(n.conf.APIKeyFile)
if err != nil {
return nil, false, errors.Wrap(err, "read key_file error")
return nil, false, fmt.Errorf("read key_file error: %w", err)
}
apiKey = tmpl(string(content))
}
if err != nil {
return nil, false, errors.Wrap(err, "templating error")
return nil, false, fmt.Errorf("templating error: %w", err)
}
for _, req := range requests {

View File

@ -17,6 +17,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -26,7 +27,6 @@ import (
"github.com/alecthomas/units"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
@ -120,7 +120,7 @@ type pagerDutyPayload struct {
func (n *Notifier) encodeMessage(msg *pagerDutyMessage) (bytes.Buffer, error) {
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return buf, errors.Wrap(err, "failed to encode PagerDuty message")
return buf, fmt.Errorf("failed to encode PagerDuty message: %w", err)
}
if buf.Len() > maxEventSize {
@ -137,7 +137,7 @@ func (n *Notifier) encodeMessage(msg *pagerDutyMessage) (bytes.Buffer, error) {
buf.Reset()
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return buf, errors.Wrap(err, "failed to encode PagerDuty message")
return buf, fmt.Errorf("failed to encode PagerDuty message: %w", err)
}
}
@ -164,7 +164,7 @@ func (n *Notifier) notifyV1(
if serviceKey == "" {
content, fileErr := os.ReadFile(n.conf.ServiceKeyFile)
if fileErr != nil {
return false, errors.Wrap(fileErr, "failed to read service key from file")
return false, fmt.Errorf("failed to read service key from file: %w", fileErr)
}
serviceKey = strings.TrimSpace(string(content))
}
@ -183,7 +183,7 @@ func (n *Notifier) notifyV1(
}
if tmplErr != nil {
return false, errors.Wrap(tmplErr, "failed to template PagerDuty v1 message")
return false, fmt.Errorf("failed to template PagerDuty v1 message: %w", tmplErr)
}
// Ensure that the service key isn't empty after templating.
@ -198,7 +198,7 @@ func (n *Notifier) notifyV1(
resp, err := notify.PostJSON(ctx, n.client, n.apiV1, &encodedMsg)
if err != nil {
return true, errors.Wrap(err, "failed to post message to PagerDuty v1")
return true, fmt.Errorf("failed to post message to PagerDuty v1: %w", err)
}
defer notify.Drain(resp)
@ -229,7 +229,7 @@ func (n *Notifier) notifyV2(
if routingKey == "" {
content, fileErr := os.ReadFile(n.conf.RoutingKeyFile)
if fileErr != nil {
return false, errors.Wrap(fileErr, "failed to read routing key from file")
return false, fmt.Errorf("failed to read routing key from file: %w", fileErr)
}
routingKey = strings.TrimSpace(string(content))
}
@ -277,7 +277,7 @@ func (n *Notifier) notifyV2(
}
if tmplErr != nil {
return false, errors.Wrap(tmplErr, "failed to template PagerDuty v2 message")
return false, fmt.Errorf("failed to template PagerDuty v2 message: %w", tmplErr)
}
// Ensure that the routing key isn't empty after templating.
@ -292,7 +292,7 @@ func (n *Notifier) notifyV2(
resp, err := notify.PostJSON(ctx, n.client, n.conf.URL.String(), &encodedMsg)
if err != nil {
return true, errors.Wrap(err, "failed to post message to PagerDuty")
return true, fmt.Errorf("failed to post message to PagerDuty: %w", err)
}
defer notify.Drain(resp)
@ -325,7 +325,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
for k, v := range n.conf.Details {
detail, err := n.tmpl.ExecuteTextString(v, data)
if err != nil {
return false, errors.Wrapf(err, "%q: failed to template %q", k, v)
return false, fmt.Errorf("%q: failed to template %q: %w", k, v, err)
}
details[k] = detail
}

View File

@ -25,7 +25,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
@ -216,7 +215,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
// classify them as retriable or not.
retry, err := n.retrier.Check(resp.StatusCode, resp.Body)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("channel %q", req.Channel))
err = fmt.Errorf("channel %q: %w", req.Channel, err)
return retry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
}
@ -224,7 +223,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
// https://slack.dev/node-slack-sdk/web-api#handle-errors
retry, err = checkResponseError(resp)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("channel %q", req.Channel))
err = fmt.Errorf("channel %q: %w", req.Channel, err)
return retry, notify.NewErrorWithReason(notify.ClientErrorReason, err)
}
@ -235,7 +234,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
func checkResponseError(resp *http.Response) (bool, error) {
body, err := io.ReadAll(resp.Body)
if err != nil {
return true, errors.Wrap(err, "could not read response body")
return true, fmt.Errorf("could not read response body: %w", err)
}
if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
@ -265,7 +264,7 @@ func checkJSONResponseError(body []byte) (bool, error) {
var data response
if err := json.Unmarshal(body, &data); err != nil {
return true, errors.Wrapf(err, "could not unmarshal JSON response %q", string(body))
return true, fmt.Errorf("could not unmarshal JSON response %q: %w", string(body), err)
}
if !data.OK {
return false, fmt.Errorf("error response from Slack: %s", data.Error)

View File

@ -15,6 +15,7 @@ package slack
import (
"context"
"errors"
"fmt"
"io"
"net/http"
@ -226,8 +227,8 @@ func TestNotifier_Notify_WithReason(t *testing.T) {
if tt.noError {
require.NoError(t, err)
} else {
reasonError, ok := err.(*notify.ErrorWithReason)
require.True(t, ok)
var reasonError *notify.ErrorWithReason
require.True(t, errors.As(err, &reasonError))
require.Equal(t, tt.expectedReason, reasonError.Reason)
require.Contains(t, err.Error(), tt.expectedErr)
require.Contains(t, err.Error(), "channelname")

View File

@ -15,6 +15,7 @@ package sns
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
@ -69,7 +70,8 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
client, err := n.createSNSClient(tmpl)
if err != nil {
if e, ok := err.(awserr.RequestFailure); ok {
var e awserr.RequestFailure
if errors.As(err, &e) {
return n.retrier.Check(e.StatusCode(), strings.NewReader(e.Message()))
}
return true, err
@ -82,7 +84,8 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
publishOutput, err := client.Publish(publishInput)
if err != nil {
if e, ok := err.(awserr.RequestFailure); ok {
var e awserr.RequestFailure
if errors.As(err, &e) {
retryable, error := n.retrier.Check(e.StatusCode(), strings.NewReader(e.Message()))
reasonErr := notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(e.StatusCode()), error)

View File

@ -16,6 +16,7 @@ package notify
import (
"context"
"crypto/sha256"
"errors"
"fmt"
"io"
"net/http"
@ -24,7 +25,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
"github.com/prometheus/common/version"
"github.com/prometheus/alertmanager/template"
@ -39,8 +39,8 @@ var UserAgentHeader = fmt.Sprintf("Alertmanager/%s", version.Version)
// RedactURL removes the URL part from an error of *url.Error type.
func RedactURL(err error) error {
e, ok := err.(*url.Error)
if !ok {
var e *url.Error
if !errors.As(err, &e) {
return err
}
e.URL = "<redacted>"
@ -160,7 +160,7 @@ type Key string
func ExtractGroupKey(ctx context.Context) (Key, error) {
key, ok := GroupKey(ctx)
if !ok {
return "", errors.Errorf("group key missing")
return "", fmt.Errorf("group key missing")
}
return Key(key), nil
}

View File

@ -24,7 +24,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
@ -83,14 +82,14 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
} else {
content, fileErr := os.ReadFile(n.conf.APIKeyFile)
if fileErr != nil {
return false, errors.Wrap(fileErr, "failed to read API key from file")
return false, fmt.Errorf("failed to read API key from file: %w", fileErr)
}
apiKey = strings.TrimSpace(string(content))
}
apiURL.Path += fmt.Sprintf("%s/%s", apiKey, tmpl(n.conf.RoutingKey))
if err != nil {
return false, fmt.Errorf("templating error: %s", err)
return false, fmt.Errorf("templating error: %w", err)
}
buf, err := n.createVictorOpsPayload(ctx, as...)
@ -155,14 +154,14 @@ func (n *Notifier) createVictorOpsPayload(ctx context.Context, as ...*types.Aler
}
if err != nil {
return nil, fmt.Errorf("templating error: %s", err)
return nil, fmt.Errorf("templating error: %w", err)
}
// Add custom fields to the payload.
for k, v := range n.conf.CustomFields {
msg[k] = tmpl(v)
if err != nil {
return nil, fmt.Errorf("templating error: %s", err)
return nil, fmt.Errorf("templating error: %w", err)
}
}

View File

@ -17,6 +17,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -25,7 +26,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
@ -101,7 +101,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
parameters.Add("corpsecret", tmpl(string(n.conf.APISecret)))
parameters.Add("corpid", tmpl(string(n.conf.CorpID)))
if err != nil {
return false, fmt.Errorf("templating error: %s", err)
return false, fmt.Errorf("templating error: %w", err)
}
u := n.conf.APIURL.Copy()
@ -147,7 +147,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
}
}
if err != nil {
return false, fmt.Errorf("templating error: %s", err)
return false, fmt.Errorf("templating error: %w", err)
}
var buf bytes.Buffer

View File

@ -14,11 +14,10 @@
package labels
import (
"fmt"
"regexp"
"strings"
"unicode/utf8"
"github.com/pkg/errors"
)
var (
@ -118,7 +117,7 @@ func ParseMatchers(s string) ([]*Matcher, error) {
func ParseMatcher(s string) (_ *Matcher, err error) {
ms := re.FindStringSubmatch(s)
if len(ms) == 0 {
return nil, errors.Errorf("bad matcher format: %s", s)
return nil, fmt.Errorf("bad matcher format: %s", s)
}
var (
@ -134,7 +133,7 @@ func ParseMatcher(s string) (_ *Matcher, err error) {
}
if !utf8.ValidString(rawValue) {
return nil, errors.Errorf("matcher value not valid UTF-8: %s", ms[3])
return nil, fmt.Errorf("matcher value not valid UTF-8: %s", ms[3])
}
// Unescape the rawValue:
@ -163,7 +162,7 @@ func ParseMatcher(s string) (_ *Matcher, err error) {
value.WriteByte('\\')
case '"':
if !expectTrailingQuote || i < len(rawValue)-1 {
return nil, errors.Errorf("matcher value contains unescaped double quote: %s", ms[3])
return nil, fmt.Errorf("matcher value contains unescaped double quote: %s", ms[3])
}
expectTrailingQuote = false
default:
@ -172,7 +171,7 @@ func ParseMatcher(s string) (_ *Matcher, err error) {
}
if expectTrailingQuote {
return nil, errors.Errorf("matcher value contains unescaped double quote: %s", ms[3])
return nil, fmt.Errorf("matcher value contains unescaped double quote: %s", ms[3])
}
return NewMatcher(typeMap[ms[2]], ms[1], value.String())

View File

@ -17,6 +17,7 @@ package silence
import (
"bytes"
"errors"
"fmt"
"io"
"math/rand"
@ -33,7 +34,6 @@ import (
"github.com/go-kit/log/level"
uuid "github.com/gofrs/uuid"
"github.com/matttproud/golang_protobuf_extensions/pbutil"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
@ -79,7 +79,7 @@ func (c matcherCache) add(s *pb.Silence) (labels.Matchers, error) {
case pb.Matcher_NOT_REGEXP:
mt = labels.MatchNotRegexp
default:
return nil, errors.Errorf("unknown matcher type %q", m.Type)
return nil, fmt.Errorf("unknown matcher type %q", m.Type)
}
matcher, err := labels.NewMatcher(mt, m.Name, m.Pattern)
if err != nil {
@ -489,7 +489,7 @@ func validateClassicMatcher(m *pb.Matcher) error {
}
case pb.Matcher_REGEXP, pb.Matcher_NOT_REGEXP:
if _, err := regexp.Compile(m.Pattern); err != nil {
return fmt.Errorf("invalid regular expression %q: %s", m.Pattern, err)
return fmt.Errorf("invalid regular expression %q: %w", m.Pattern, err)
}
default:
return fmt.Errorf("unknown matcher type %q", m.Type)
@ -512,7 +512,7 @@ func validateUTF8Matcher(m *pb.Matcher) error {
return fmt.Errorf("invalid regular expression %q", m.Pattern)
}
if _, err := regexp.Compile(m.Pattern); err != nil {
return fmt.Errorf("invalid regular expression %q: %s", m.Pattern, err)
return fmt.Errorf("invalid regular expression %q: %w", m.Pattern, err)
}
default:
return fmt.Errorf("unknown matcher type %q", m.Type)
@ -548,7 +548,7 @@ func validateSilence(s *pb.Silence, ff featurecontrol.Flagger) error {
for i, m := range s.Matchers {
if err := validateFunc(m); err != nil {
return fmt.Errorf("invalid label matcher %d: %s", i, err)
return fmt.Errorf("invalid label matcher %d: %w", i, err)
}
allMatchEmpty = allMatchEmpty && matchesEmpty(m)
}
@ -589,7 +589,7 @@ func (s *Silences) setSilence(sil *pb.Silence, now time.Time, skipValidate bool)
if !skipValidate {
if err := validateSilence(sil, s.ff); err != nil {
return errors.Wrap(err, "silence invalid")
return fmt.Errorf("silence invalid: %w", err)
}
}
@ -629,14 +629,14 @@ func (s *Silences) Set(sil *pb.Silence) (string, error) {
if getState(prev, s.nowUTC()) != types.SilenceStateExpired {
// We cannot update the silence, expire the old one.
if err := s.expire(prev.Id); err != nil {
return "", errors.Wrap(err, "expire previous silence")
return "", fmt.Errorf("expire previous silence: %w", err)
}
}
}
// If we got here it's either a new silence or a replacing one.
uid, err := uuid.NewV4()
if err != nil {
return "", errors.Wrap(err, "generate uuid")
return "", fmt.Errorf("generate uuid: %w", err)
}
sil.Id = uid.String()
@ -994,7 +994,7 @@ func decodeState(r io.Reader) (state, error) {
st[s.Silence.Id] = &s
continue
}
if err == io.EOF {
if errors.Is(err, io.EOF) {
break
}
return nil, err

View File

@ -294,14 +294,14 @@ func (amc *AlertmanagerCluster) Start() error {
for _, am := range amc.ams {
err := am.Start(peerFlags)
if err != nil {
return fmt.Errorf("starting alertmanager cluster: %v", err.Error())
return fmt.Errorf("starting alertmanager cluster: %w", err)
}
}
for _, am := range amc.ams {
err := am.WaitForCluster(len(amc.ams))
if err != nil {
return fmt.Errorf("waiting alertmanager cluster: %v", err.Error())
return fmt.Errorf("waiting alertmanager cluster: %w", err)
}
}
@ -342,7 +342,7 @@ func (am *Alertmanager) Start(additionalArg []string) error {
am.cmd = cmd
if err := am.cmd.Start(); err != nil {
return fmt.Errorf("starting alertmanager failed: %s", err)
return fmt.Errorf("starting alertmanager failed: %w", err)
}
go func() {
@ -364,7 +364,7 @@ func (am *Alertmanager) Start(additionalArg []string) error {
}
_, err = io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("starting alertmanager failed: %s", err)
return fmt.Errorf("starting alertmanager failed: %w", err)
}
return nil
}

View File

@ -274,14 +274,14 @@ func (amc *AlertmanagerCluster) Start() error {
for _, am := range amc.ams {
err := am.Start(peerFlags)
if err != nil {
return fmt.Errorf("failed to start alertmanager cluster: %v", err.Error())
return fmt.Errorf("failed to start alertmanager cluster: %w", err)
}
}
for _, am := range amc.ams {
err := am.WaitForCluster(len(amc.ams))
if err != nil {
return fmt.Errorf("failed to wait for Alertmanager instance %q to join cluster: %v", am.clusterAddr, err.Error())
return fmt.Errorf("failed to wait for Alertmanager instance %q to join cluster: %w", am.clusterAddr, err)
}
}
@ -343,7 +343,7 @@ func (am *Alertmanager) Start(additionalArg []string) error {
}
time.Sleep(500 * time.Millisecond)
}
return fmt.Errorf("unable to get a successful response from the Alertmanager: %v", lastErr)
return fmt.Errorf("unable to get a successful response from the Alertmanager: %w", lastErr)
}
// WaitForCluster waits for the Alertmanager instance to join a cluster with the

View File

@ -345,10 +345,10 @@ func (a *Alert) Validate(ff featurecontrol.Flagger) error {
return fmt.Errorf("at least one label pair required")
}
if err := validateLs(a.Labels, ff); err != nil {
return fmt.Errorf("invalid label set: %s", err)
return fmt.Errorf("invalid label set: %w", err)
}
if err := validateLs(a.Annotations, ff); err != nil {
return fmt.Errorf("invalid annotations: %s", err)
return fmt.Errorf("invalid annotations: %w", err)
}
return nil
}