Skip to content

Commit b4fe634

Browse files
authored
refactor: replace go-multierror with stdlib go multierrors (#5240)
* refactor: replace go-multierror with stdlib go multierrors replace go-multierror with stdlib errors.Join * lint: fix linter issues
1 parent b3afeaf commit b4fe634

File tree

16 files changed

+7347
-7372
lines changed

16 files changed

+7347
-7372
lines changed

NOTICE.txt

+7,290-7,290
Large diffs are not rendered by default.

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ require (
3030
github.com/google/go-cmp v0.6.0
3131
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba
3232
github.com/gorilla/mux v1.8.1
33-
github.com/hashicorp/go-multierror v1.1.1
3433
github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95
3534
github.com/jaypipes/ghw v0.12.0
3635
github.com/jedib0t/go-pretty/v6 v6.4.6
@@ -216,6 +215,7 @@ require (
216215
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
217216
github.com/hashicorp/go-hclog v1.6.3 // indirect
218217
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
218+
github.com/hashicorp/go-multierror v1.1.1 // indirect
219219
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
220220
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
221221
github.com/hashicorp/golang-lru v1.0.2 // indirect

internal/pkg/agent/application/coordinator/coordinator.go

+7-9
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
"sync/atomic"
1414
"time"
1515

16-
"github.com/hashicorp/go-multierror"
17-
1816
"go.elastic.co/apm/v2"
1917
"gopkg.in/yaml.v2"
2018

@@ -1571,7 +1569,7 @@ func collectManagerErrors(timeout time.Duration, varsErrCh, runtimeErrCh, config
15711569

15721570
// combinedErr will store any reported errors as well as timeout errors
15731571
// for unresponsive managers.
1574-
var combinedErr error
1572+
var errs []error
15751573

15761574
waitLoop:
15771575
for !returnedRuntime || !returnedConfig || !returnedVars || !returnedUpgradeMarkerWatcher {
@@ -1599,23 +1597,23 @@ waitLoop:
15991597
timeouts = append(timeouts, "no response from upgrade marker watcher")
16001598
}
16011599
timeoutStr := strings.Join(timeouts, ", ")
1602-
combinedErr = multierror.Append(combinedErr, fmt.Errorf("timeout while waiting for managers to shut down: %v", timeoutStr))
1600+
errs = append(errs, fmt.Errorf("timeout while waiting for managers to shut down: %v", timeoutStr))
16031601
break waitLoop
16041602
}
16051603
}
16061604
if runtimeErr != nil && !errors.Is(runtimeErr, context.Canceled) {
1607-
combinedErr = multierror.Append(combinedErr, fmt.Errorf("runtime manager: %w", runtimeErr))
1605+
errs = append(errs, fmt.Errorf("runtime manager: %w", runtimeErr))
16081606
}
16091607
if configErr != nil && !errors.Is(configErr, context.Canceled) {
1610-
combinedErr = multierror.Append(combinedErr, fmt.Errorf("config manager: %w", configErr))
1608+
errs = append(errs, fmt.Errorf("config manager: %w", configErr))
16111609
}
16121610
if varsErr != nil && !errors.Is(varsErr, context.Canceled) {
1613-
combinedErr = multierror.Append(combinedErr, fmt.Errorf("vars manager: %w", varsErr))
1611+
errs = append(errs, fmt.Errorf("vars manager: %w", varsErr))
16141612
}
16151613
if upgradeMarkerWatcherErr != nil && !errors.Is(upgradeMarkerWatcherErr, context.Canceled) {
1616-
combinedErr = multierror.Append(combinedErr, fmt.Errorf("upgrade marker watcher: %w", upgradeMarkerWatcherErr))
1614+
errs = append(errs, fmt.Errorf("upgrade marker watcher: %w", upgradeMarkerWatcherErr))
16171615
}
1618-
return combinedErr
1616+
return errors.Join(errs...)
16191617
}
16201618

16211619
type coordinatorComponentLog struct {

internal/pkg/agent/application/coordinator/coordinator_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ func TestCollectManagerErrorsTimeout(t *testing.T) {
658658
// in collectManagerErrors
659659
waitAndTestError(t, func(err error) bool {
660660
return err != nil &&
661-
strings.Contains(err.Error(), "1 error occurred") &&
662661
strings.Contains(err.Error(), "timeout while waiting for managers")
663662
}, handlerChan)
664663
}
@@ -673,7 +672,6 @@ func TestCollectManagerErrorsOneResponse(t *testing.T) {
673672

674673
waitAndTestError(t, func(err error) bool {
675674
return err != nil &&
676-
strings.Contains(err.Error(), "2 errors occurred") &&
677675
strings.Contains(err.Error(), cfgErrStr) &&
678676
strings.Contains(err.Error(), "timeout while waiting for managers")
679677
}, handlerChan)
@@ -691,7 +689,6 @@ func TestCollectManagerErrorsAllResponses(t *testing.T) {
691689

692690
waitAndTestError(t, func(err error) bool {
693691
return err != nil &&
694-
strings.Contains(err.Error(), "3 errors occurred") &&
695692
strings.Contains(err.Error(), runtimeErrStr) &&
696693
strings.Contains(err.Error(), varsErrStr) &&
697694
strings.Contains(err.Error(), upgradeMarkerWatcherErrStr)

internal/pkg/agent/application/upgrade/artifact/download/composed/downloader.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ package composed
66

77
import (
88
"context"
9+
goerrors "errors"
910

10-
"github.com/hashicorp/go-multierror"
1111
"go.elastic.co/apm/v2"
1212

1313
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
@@ -37,7 +37,7 @@ func NewDownloader(downloaders ...download.Downloader) *Downloader {
3737
// Download fetches the package from configured source.
3838
// Returns absolute path to downloaded package and an error.
3939
func (e *Downloader) Download(ctx context.Context, a artifact.Artifact, version *version.ParsedSemVer) (string, error) {
40-
var err error
40+
var errs []error
4141
span, ctx := apm.StartSpan(ctx, "download", "app.internal")
4242
defer span.End()
4343

@@ -47,10 +47,10 @@ func (e *Downloader) Download(ctx context.Context, a artifact.Artifact, version
4747
return s, nil
4848
}
4949

50-
err = multierror.Append(err, e)
50+
errs = append(errs, e)
5151
}
5252

53-
return "", err
53+
return "", goerrors.Join(errs...)
5454
}
5555

5656
func (e *Downloader) Reload(c *artifact.Config) error {

internal/pkg/agent/application/upgrade/artifact/download/composed/verifier.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
package composed
66

77
import (
8-
"github.com/hashicorp/go-multierror"
8+
goerrors "errors"
99

1010
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
1111
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact/download"
@@ -40,7 +40,7 @@ func NewVerifier(log *logger.Logger, verifiers ...download.Verifier) *Verifier {
4040

4141
// Verify checks the package from configured source.
4242
func (v *Verifier) Verify(a artifact.Artifact, version agtversion.ParsedSemVer, skipDefaultPgp bool, pgpBytes ...string) error {
43-
var err error
43+
var errs []error
4444

4545
for _, verifier := range v.vv {
4646
e := verifier.Verify(a, version, skipDefaultPgp, pgpBytes...)
@@ -50,10 +50,10 @@ func (v *Verifier) Verify(a artifact.Artifact, version agtversion.ParsedSemVer,
5050
}
5151

5252
v.log.Debugw("Verifier failed!", "verifier", verifier.Name(), "error", e)
53-
err = multierror.Append(err, e)
53+
errs = append(errs, e)
5454
}
5555

56-
return err
56+
return goerrors.Join(errs...)
5757
}
5858

5959
func (v *Verifier) Reload(c *artifact.Config) error {

internal/pkg/agent/application/upgrade/artifact/download/verifier.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"context"
1111
"crypto/sha512"
1212
"encoding/hex"
13+
goerrors "errors"
1314
"fmt"
1415
"hash"
1516
"io"
@@ -20,7 +21,6 @@ import (
2021
"strings"
2122
"time"
2223

23-
"github.com/hashicorp/go-multierror"
2424
"golang.org/x/crypto/openpgp" //nolint:staticcheck // crypto/openpgp is only receiving security updates.
2525

2626
"github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/artifact"
@@ -309,7 +309,7 @@ func CheckValidDownloadUri(rawURI string) error {
309309
}
310310

311311
if !strings.EqualFold(uri.Scheme, "https") {
312-
return multierror.Append(fmt.Errorf("failed to check URI %q: HTTPS is required", rawURI), ErrInvalidLocation)
312+
return fmt.Errorf("failed to check URI %q: HTTPS is required: %w", rawURI, ErrInvalidLocation)
313313
}
314314

315315
return nil
@@ -329,7 +329,7 @@ func fetchPgpFromURI(uri string, client HTTPClient) ([]byte, error) {
329329
}
330330
resp, err := client.Do(req)
331331
if err != nil {
332-
return nil, multierror.Append(err, ErrRemotePGPDownloadFailed)
332+
return nil, goerrors.Join(err, ErrRemotePGPDownloadFailed)
333333
}
334334
defer resp.Body.Close()
335335

internal/pkg/agent/application/upgrade/cleanup.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55
package upgrade
66

77
import (
8+
"errors"
89
"fmt"
910
"os"
1011
"path/filepath"
1112
"strings"
1213

13-
"github.com/hashicorp/go-multierror"
14-
1514
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
1615
"github.com/elastic/elastic-agent/pkg/core/logger"
1716
)
@@ -30,16 +29,16 @@ func cleanNonMatchingVersionsFromDownloads(log *logger.Logger, version string) e
3029
if err != nil {
3130
return fmt.Errorf("unable to read directory %q: %w", paths.Downloads(), err)
3231
}
33-
var rErr error
32+
var errs []error
3433
for _, file := range files {
3534
if file.IsDir() {
3635
continue
3736
}
3837
if !strings.Contains(file.Name(), version) {
3938
if err := os.Remove(filepath.Join(paths.Downloads(), file.Name())); err != nil {
40-
rErr = multierror.Append(rErr, fmt.Errorf("unable to remove file %q: %w", filepath.Join(paths.Downloads(), file.Name()), err))
39+
errs = append(errs, fmt.Errorf("unable to remove file %q: %w", filepath.Join(paths.Downloads(), file.Name()), err))
4140
}
4241
}
4342
}
44-
return rErr
43+
return errors.Join(errs...)
4544
}

internal/pkg/agent/application/upgrade/rollback.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ package upgrade
66

77
import (
88
"context"
9+
goerrors "errors"
910
"fmt"
1011
"os"
1112
"os/exec"
1213
"path/filepath"
1314
"strings"
1415
"time"
1516

16-
"github.com/hashicorp/go-multierror"
1717
"google.golang.org/grpc"
1818

1919
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
@@ -114,6 +114,7 @@ func Cleanup(log *logger.Logger, topDirPath, currentVersionedHome, currentHash s
114114
currentDir = fmt.Sprintf("%s-%s", agentName, currentHash)
115115
}
116116

117+
var errs []error
117118
for _, dir := range subdirs {
118119
if dir == currentDir {
119120
continue
@@ -130,11 +131,11 @@ func Cleanup(log *logger.Logger, topDirPath, currentVersionedHome, currentHash s
130131
ignoredDirs = append(ignoredDirs, "logs")
131132
}
132133
if cleanupErr := install.RemoveBut(hashedDir, true, ignoredDirs...); cleanupErr != nil {
133-
err = multierror.Append(err, cleanupErr)
134+
errs = append(errs, cleanupErr)
134135
}
135136
}
136137

137-
return err
138+
return goerrors.Join(errs...)
138139
}
139140

140141
// InvokeWatcher invokes an agent instance using watcher argument for watching behavior of
@@ -170,6 +171,7 @@ func restartAgent(ctx context.Context, log *logger.Logger, c client.Client) erro
170171
restartViaDaemonFn := func(ctx context.Context) error {
171172
connectCtx, connectCancel := context.WithTimeout(ctx, 3*time.Second)
172173
defer connectCancel()
174+
//nolint:staticcheck // requires changing client signature
173175
err := c.Connect(connectCtx, grpc.WithBlock(), grpc.WithDisableRetry())
174176
if err != nil {
175177
return errors.New(err, "failed communicating to running daemon", errors.TypeNetwork, errors.M("socket", control.Address()))

internal/pkg/agent/application/upgrade/watcher.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"fmt"
1111
"time"
1212

13-
"github.com/hashicorp/go-multierror"
1413
"google.golang.org/grpc"
1514

1615
"github.com/elastic/elastic-agent/pkg/control/v2/client"
@@ -134,6 +133,7 @@ LOOP:
134133
// block on connection, don't retry connection, and fail on temp dial errors
135134
// always a local connection it should connect quickly so the timeout is only 1 second
136135
connectCtx, connectCancel := context.WithTimeout(ctx, 1*time.Second)
136+
//nolint:staticcheck // requires changing client signature
137137
err := ch.agentClient.Connect(connectCtx, grpc.WithBlock(), grpc.WithDisableRetry(), grpc.FailOnNonTempDialError(true))
138138
connectCancel()
139139
if err != nil {
@@ -215,14 +215,14 @@ LOOP:
215215
} else {
216216
// agent is healthy; but a component might not be healthy
217217
// upgrade tracks unhealthy component as an issue with the upgrade
218-
var compErr error
218+
var errs []error
219219
for _, comp := range state.Components {
220220
if comp.State == client.Failed {
221-
compErr = multierror.Append(compErr, fmt.Errorf("component %s[%v] failed: %s", comp.Name, comp.ID, comp.Message))
221+
errs = append(errs, fmt.Errorf("component %s[%v] failed: %s", comp.Name, comp.ID, comp.Message))
222222
}
223223
}
224-
if compErr != nil {
225-
failedCh <- fmt.Errorf("%w: %w", ErrAgentComponentFailed, compErr)
224+
if len(errs) != 0 {
225+
failedCh <- fmt.Errorf("%w: %w", ErrAgentComponentFailed, errors.Join(errs...))
226226
continue
227227
}
228228
}

internal/pkg/agent/cmd/otel.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ package cmd
88

99
import (
1010
"context"
11+
goerrors "errors"
1112
"sync"
1213

13-
"github.com/hashicorp/go-multierror"
1414
"github.com/spf13/cobra"
1515
"github.com/spf13/pflag"
1616

@@ -80,7 +80,7 @@ func runCollector(cmdCtx context.Context, configFiles []string) error {
8080
go service.ProcessWindowsControlEvents(stopCollector)
8181

8282
var otelStartWg sync.WaitGroup
83-
var resErr error
83+
var errs []error
8484
var awaiters awaiters
8585

8686
otelAwaiter := make(chan struct{})
@@ -90,7 +90,7 @@ func runCollector(cmdCtx context.Context, configFiles []string) error {
9090
go func() {
9191
otelStartWg.Done()
9292
if err := otel.Run(ctx, stop, configFiles); err != nil {
93-
resErr = multierror.Append(resErr, err)
93+
errs = append(errs, err)
9494
// otel collector finished with an error, exit run loop
9595
cancel()
9696
}
@@ -112,9 +112,9 @@ func runCollector(cmdCtx context.Context, configFiles []string) error {
112112
true, // is otel mode
113113
awaiters, // wait for otel to finish
114114
); err != nil && !errors.Is(err, context.Canceled) {
115-
resErr = multierror.Append(resErr, err)
115+
errs = append(errs, err)
116116
}
117117

118-
return resErr
118+
return goerrors.Join(errs...)
119119

120120
}

internal/pkg/eql/expression.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"fmt"
1010

1111
"github.com/antlr4-go/antlr/v4"
12-
"github.com/hashicorp/go-multierror"
1312

1413
"github.com/elastic/elastic-agent/internal/pkg/eql/parser"
1514
)
@@ -108,6 +107,6 @@ func (el *errorListener) SyntaxError(
108107
msg string,
109108
e antlr.RecognitionException,
110109
) {
111-
el.errors = multierror.Append(el.errors,
110+
el.errors = errors.Join(el.errors,
112111
fmt.Errorf("condition line %d column %d: %v", line, column, msg))
113112
}

0 commit comments

Comments
 (0)