diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index fb6df26b1ad..acd7aea7d26 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -1,11 +1,10 @@ package config import ( + "errors" "math/big" "time" - "go.uber.org/multierr" - ocr "github.com/smartcontractkit/libocr/offchainreporting" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types" @@ -57,7 +56,7 @@ func (c *ChainScoped) Validate() (err error) { DataSourceGracePeriod: c.EVM().OCR().ObservationGracePeriod(), } if ocrerr := ocr.SanityCheckLocalConfig(lc); ocrerr != nil { - err = multierr.Append(err, ocrerr) + err = errors.Join(err, ocrerr) } return } diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 2348e648696..d314561bac6 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -1,6 +1,7 @@ package toml import ( + "errors" "fmt" "net/url" "slices" @@ -9,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/core/txpool/legacypool" "github.com/pelletier/go-toml/v2" "github.com/shopspring/decimal" - "go.uber.org/multierr" "gopkg.in/guregu/null.v4" commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" @@ -39,7 +39,7 @@ func (cs EVMConfigs) validateKeys() (err error) { chainIDs := commonconfig.UniqueStrings{} for i, c := range cs { if chainIDs.IsDupeFmt(c.ChainID) { - err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), c.ChainID.String())) + err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.ChainID", i), c.ChainID.String())) } } @@ -48,7 +48,7 @@ func (cs EVMConfigs) validateKeys() (err error) { for i, c := range cs { for j, n := range c.Nodes { if names.IsDupe(n.Name) { - err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name)) + err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.Name", i, j), *n.Name)) } } } @@ -59,7 +59,7 @@ func (cs EVMConfigs) validateKeys() (err error) { for j, n := range c.Nodes { u := (*url.URL)(n.WSURL) if wsURLs.IsDupeFmt(u) { - err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.WSURL", i, j), u.String())) + err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.WSURL", i, j), u.String())) } } } @@ -70,7 +70,7 @@ func (cs EVMConfigs) validateKeys() (err error) { for j, n := range c.Nodes { u := (*url.URL)(n.HTTPURL) if httpURLs.IsDupeFmt(u) { - err = multierr.Append(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.HTTPURL", i, j), u.String())) + err = errors.Join(err, commonconfig.NewErrDuplicate(fmt.Sprintf("%d.Nodes.%d.HTTPURL", i, j), u.String())) } } } @@ -289,29 +289,29 @@ func (c *EVMConfig) SetFrom(f *EVMConfig) { func (c *EVMConfig) ValidateConfig() (err error) { if c.ChainID == nil { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "ChainID", Msg: "required for all chains"}) + err = errors.Join(err, commonconfig.ErrMissing{Name: "ChainID", Msg: "required for all chains"}) } else if c.ChainID.String() == "" { - err = multierr.Append(err, commonconfig.ErrEmpty{Name: "ChainID", Msg: "required for all chains"}) + err = errors.Join(err, commonconfig.ErrEmpty{Name: "ChainID", Msg: "required for all chains"}) } else if must, ok := ChainTypeForID(c.ChainID); ok { // known chain id if c.ChainType == nil && must != "" { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "ChainType", + err = errors.Join(err, commonconfig.ErrMissing{Name: "ChainType", Msg: fmt.Sprintf("only %q can be used with this chain id", must)}) } else if c.ChainType != nil && *c.ChainType != string(must) { if *c.ChainType == "" { - err = multierr.Append(err, commonconfig.ErrEmpty{Name: "ChainType", + err = errors.Join(err, commonconfig.ErrEmpty{Name: "ChainType", Msg: fmt.Sprintf("only %q can be used with this chain id", must)}) } else if must == "" { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, Msg: "must not be set with this chain id"}) } else { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, Msg: fmt.Sprintf("only %q can be used with this chain id", must)}) } } } if len(c.Nodes) == 0 { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "Nodes", Msg: "must have at least one node"}) + err = errors.Join(err, commonconfig.ErrMissing{Name: "Nodes", Msg: "must have at least one node"}) } else { var hasPrimary bool for _, n := range c.Nodes { @@ -322,12 +322,12 @@ func (c *EVMConfig) ValidateConfig() (err error) { break } if !hasPrimary { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "Nodes", + err = errors.Join(err, commonconfig.ErrMissing{Name: "Nodes", Msg: "must have at least one primary node with WSURL"}) } } - err = multierr.Append(err, c.Chain.ValidateConfig()) + err = errors.Join(err, c.Chain.ValidateConfig()) return } @@ -376,24 +376,24 @@ func (c *Chain) ValidateConfig() (err error) { chainType = config.ChainType(*c.ChainType) } if !chainType.IsValid() { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "ChainType", Value: *c.ChainType, Msg: config.ErrInvalidChainType.Error()}) } if c.GasEstimator.BumpTxDepth != nil && *c.GasEstimator.BumpTxDepth > *c.Transactions.MaxInFlight { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "GasEstimator.BumpTxDepth", Value: *c.GasEstimator.BumpTxDepth, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "GasEstimator.BumpTxDepth", Value: *c.GasEstimator.BumpTxDepth, Msg: "must be less than or equal to Transactions.MaxInFlight"}) } if *c.HeadTracker.HistoryDepth < *c.FinalityDepth { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "HeadTracker.HistoryDepth", Value: *c.HeadTracker.HistoryDepth, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "HeadTracker.HistoryDepth", Value: *c.HeadTracker.HistoryDepth, Msg: "must be equal to or greater than FinalityDepth"}) } if *c.FinalityDepth < 1 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FinalityDepth", Value: *c.FinalityDepth, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "FinalityDepth", Value: *c.FinalityDepth, Msg: "must be greater than or equal to 1"}) } if *c.MinIncomingConfirmations < 1 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "MinIncomingConfirmations", Value: *c.MinIncomingConfirmations, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "MinIncomingConfirmations", Value: *c.MinIncomingConfirmations, Msg: "must be greater than or equal to 1"}) } return @@ -486,36 +486,36 @@ type GasEstimator struct { func (e *GasEstimator) ValidateConfig() (err error) { if uint64(*e.BumpPercent) < legacypool.DefaultConfig.PriceBump { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "BumpPercent", Value: *e.BumpPercent, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "BumpPercent", Value: *e.BumpPercent, Msg: fmt.Sprintf("may not be less than Geth's default of %d", legacypool.DefaultConfig.PriceBump)}) } if e.TipCapDefault.Cmp(e.TipCapMin) < 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "TipCapDefault", Value: e.TipCapDefault, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "TipCapDefault", Value: e.TipCapDefault, Msg: "must be greater than or equal to TipCapMinimum"}) } if e.FeeCapDefault.Cmp(e.TipCapDefault) < 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.TipCapDefault, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.TipCapDefault, Msg: "must be greater than or equal to TipCapDefault"}) } if *e.Mode == "FixedPrice" && *e.BumpThreshold == 0 && *e.EIP1559DynamicFees && e.FeeCapDefault.Cmp(e.PriceMax) != 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault, Msg: fmt.Sprintf("must be equal to PriceMax (%s) since you are using FixedPrice estimation with gas bumping disabled in "+ "EIP1559 mode - PriceMax will be used as the FeeCap for transactions instead of FeeCapDefault", e.PriceMax)}) } else if e.FeeCapDefault.Cmp(e.PriceMax) > 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "FeeCapDefault", Value: e.FeeCapDefault, Msg: fmt.Sprintf("must be less than or equal to PriceMax (%s)", e.PriceMax)}) } if e.PriceMin.Cmp(e.PriceDefault) > 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "PriceMin", Value: e.PriceMin, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "PriceMin", Value: e.PriceMin, Msg: "must be less than or equal to PriceDefault"}) } if e.PriceMax.Cmp(e.PriceDefault) < 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "PriceMax", Value: e.PriceMin, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "PriceMax", Value: e.PriceMin, Msg: "must be greater than or equal to PriceDefault"}) } if *e.Mode == "BlockHistory" && *e.BlockHistory.BlockHistorySize <= 0 { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "BlockHistory.BlockHistorySize", Value: *e.BlockHistory.BlockHistorySize, + err = errors.Join(err, commonconfig.ErrInvalid{Name: "BlockHistory.BlockHistorySize", Value: *e.BlockHistory.BlockHistorySize, Msg: "must be greater than or equal to 1 with BlockHistory Mode"}) } @@ -642,7 +642,7 @@ func (ks KeySpecificConfig) ValidateConfig() (err error) { for _, k := range ks { addr := k.Key.String() if _, ok := addrs[addr]; ok { - err = multierr.Append(err, commonconfig.NewErrDuplicate("Key", addr)) + err = errors.Join(err, commonconfig.NewErrDuplicate("Key", addr)) } else { addrs[addr] = struct{}{} } @@ -749,9 +749,9 @@ type Node struct { func (n *Node) ValidateConfig() (err error) { if n.Name == nil { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "Name", Msg: "required for all nodes"}) + err = errors.Join(err, commonconfig.ErrMissing{Name: "Name", Msg: "required for all nodes"}) } else if *n.Name == "" { - err = multierr.Append(err, commonconfig.ErrEmpty{Name: "Name", Msg: "required for all nodes"}) + err = errors.Join(err, commonconfig.ErrEmpty{Name: "Name", Msg: "required for all nodes"}) } var sendOnly bool @@ -760,34 +760,34 @@ func (n *Node) ValidateConfig() (err error) { } if n.WSURL == nil { if !sendOnly { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "WSURL", Msg: "required for primary nodes"}) + err = errors.Join(err, commonconfig.ErrMissing{Name: "WSURL", Msg: "required for primary nodes"}) } } else if n.WSURL.IsZero() { if !sendOnly { - err = multierr.Append(err, commonconfig.ErrEmpty{Name: "WSURL", Msg: "required for primary nodes"}) + err = errors.Join(err, commonconfig.ErrEmpty{Name: "WSURL", Msg: "required for primary nodes"}) } } else { switch n.WSURL.Scheme { case "ws", "wss": default: - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "WSURL", Value: n.WSURL.Scheme, Msg: "must be ws or wss"}) + err = errors.Join(err, commonconfig.ErrInvalid{Name: "WSURL", Value: n.WSURL.Scheme, Msg: "must be ws or wss"}) } } if n.HTTPURL == nil { - err = multierr.Append(err, commonconfig.ErrMissing{Name: "HTTPURL", Msg: "required for all nodes"}) + err = errors.Join(err, commonconfig.ErrMissing{Name: "HTTPURL", Msg: "required for all nodes"}) } else if n.HTTPURL.IsZero() { - err = multierr.Append(err, commonconfig.ErrEmpty{Name: "HTTPURL", Msg: "required for all nodes"}) + err = errors.Join(err, commonconfig.ErrEmpty{Name: "HTTPURL", Msg: "required for all nodes"}) } else { switch n.HTTPURL.Scheme { case "http", "https": default: - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "HTTPURL", Value: n.HTTPURL.Scheme, Msg: "must be http or https"}) + err = errors.Join(err, commonconfig.ErrInvalid{Name: "HTTPURL", Value: n.HTTPURL.Scheme, Msg: "must be http or https"}) } } if n.Order != nil && (*n.Order < 1 || *n.Order > 100) { - err = multierr.Append(err, commonconfig.ErrInvalid{Name: "Order", Value: *n.Order, Msg: "must be between 1 and 100"}) + err = errors.Join(err, commonconfig.ErrInvalid{Name: "Order", Value: *n.Order, Msg: "must be between 1 and 100"}) } else if n.Order == nil { z := int32(100) n.Order = &z diff --git a/core/cmd/admin_commands.go b/core/cmd/admin_commands.go index 799709ad205..a87ffa0a130 100644 --- a/core/cmd/admin_commands.go +++ b/core/cmd/admin_commands.go @@ -15,7 +15,6 @@ import ( "github.com/manyminds/api2go/jsonapi" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" @@ -186,7 +185,7 @@ func (s *Shell) ListUsers(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -201,7 +200,7 @@ func (s *Shell) CreateUser(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() var links jsonapi.Links @@ -240,7 +239,7 @@ func (s *Shell) CreateUser(c *cli.Context) (err error) { } defer func() { if cerr := response.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -269,7 +268,7 @@ func (s *Shell) ChangeRole(c *cli.Context) (err error) { } defer func() { if cerr := response.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -289,7 +288,7 @@ func (s *Shell) DeleteUser(c *cli.Context) (err error) { } defer func() { if cerr := response.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -304,7 +303,7 @@ func (s *Shell) Status(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/blocks_commands.go b/core/cmd/blocks_commands.go index 72b0523e18d..74c24095072 100644 --- a/core/cmd/blocks_commands.go +++ b/core/cmd/blocks_commands.go @@ -2,13 +2,13 @@ package cmd import ( "bytes" + "errors" "fmt" "net/url" "strconv" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" ) func initBlocksSubCmds(s *Shell) []cli.Command { @@ -41,7 +41,7 @@ func initBlocksSubCmds(s *Shell) []cli.Command { func (s *Shell) ReplayFromBlock(c *cli.Context) (err error) { blockNumber := c.Int64("block-number") if blockNumber <= 0 { - return s.errorOut(errors.New("Must pass a positive value in '--block-number' parameter")) + return s.errorOut(pkgerrors.New("Must pass a positive value in '--block-number' parameter")) } v := url.Values{} @@ -64,7 +64,7 @@ func (s *Shell) ReplayFromBlock(c *cli.Context) (err error) { defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/bridge_commands.go b/core/cmd/bridge_commands.go index 398d466c43a..a0208eb738d 100644 --- a/core/cmd/bridge_commands.go +++ b/core/cmd/bridge_commands.go @@ -5,7 +5,6 @@ import ( "strconv" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -97,7 +96,7 @@ func (s *Shell) ShowBridge(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -121,7 +120,7 @@ func (s *Shell) CreateBridge(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -140,7 +139,7 @@ func (s *Shell) RemoveBridge(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/cosmos_transaction_commands.go b/core/cmd/cosmos_transaction_commands.go index 0e9febeb70c..1dfc60226a6 100644 --- a/core/cmd/cosmos_transaction_commands.go +++ b/core/cmd/cosmos_transaction_commands.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/store/models/cosmos" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" @@ -121,7 +120,7 @@ func (s *Shell) CosmosSendNativeToken(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/csa_keys_commands.go b/core/cmd/csa_keys_commands.go index 1c0fe54ab09..ff8a50babb5 100644 --- a/core/cmd/csa_keys_commands.go +++ b/core/cmd/csa_keys_commands.go @@ -2,15 +2,15 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "net/url" "os" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -114,7 +114,7 @@ func (s *Shell) ListCSAKeys(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -129,7 +129,7 @@ func (s *Shell) CreateCSAKey(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -139,16 +139,16 @@ func (s *Shell) CreateCSAKey(_ *cli.Context) (err error) { // ImportCSAKey imports and stores a CSA key. Path to key must be passed. func (s *Shell) ImportCSAKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -171,7 +171,7 @@ func (s *Shell) ImportCSAKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -181,22 +181,22 @@ func (s *Shell) ImportCSAKey(c *cli.Context) (err error) { // ExportCSAKey exports a CSA key. Key ID must be passed. func (s *Shell) ExportCSAKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the ID of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the ID of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } ID := c.Args().Get(0) @@ -210,11 +210,11 @@ func (s *Shell) ExportCSAKey(c *cli.Context) (err error) { exportUrl.RawQuery = query.Encode() resp, err := s.HTTP.Post(s.ctx(), exportUrl.String(), nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -224,12 +224,12 @@ func (s *Shell) ExportCSAKey(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("🔑 Exported P2P key %s to %s\n", ID, filepath)) diff --git a/core/cmd/eth_keys_commands.go b/core/cmd/eth_keys_commands.go index 5adac3b382b..d4c3632e01c 100644 --- a/core/cmd/eth_keys_commands.go +++ b/core/cmd/eth_keys_commands.go @@ -3,6 +3,7 @@ package cmd import ( "bytes" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -10,9 +11,8 @@ import ( "os" "strings" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -183,7 +183,7 @@ func (s *Shell) ListETHKeys(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -212,7 +212,7 @@ func (s *Shell) CreateETHKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -223,7 +223,7 @@ func (s *Shell) CreateETHKey(c *cli.Context) (err error) { // address of key must be passed func (s *Shell) DeleteETHKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the address of the key to be deleted")) + return s.errorOut(pkgerrors.New("Must pass the address of the key to be deleted")) } address := c.Args().Get(0) @@ -237,21 +237,21 @@ func (s *Shell) DeleteETHKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() if resp.StatusCode != http.StatusOK { body, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Failed to read request response")) + return s.errorOut(pkgerrors.Wrap(err, "Failed to read request response")) } var result *models.JSONAPIErrors err = json.Unmarshal(body, &result) if err != nil { - return s.errorOut(errors.Wrapf(err, "Unable to unmarshal json from body '%s'", string(body))) + return s.errorOut(pkgerrors.Wrapf(err, "Unable to unmarshal json from body '%s'", string(body))) } - return s.errorOut(errors.Errorf("Delete ETH key failed: %s", result.Error())) + return s.errorOut(pkgerrors.Errorf("Delete ETH key failed: %s", result.Error())) } return s.renderAPIResponse(resp, &EthKeyPresenter{}, fmt.Sprintf("🔑 Deleted ETH key: %s\n", address)) } @@ -260,16 +260,16 @@ func (s *Shell) DeleteETHKey(c *cli.Context) (err error) { // file path must be passed func (s *Shell) ImportETHKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -296,7 +296,7 @@ func (s *Shell) ImportETHKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -307,21 +307,21 @@ func (s *Shell) ImportETHKey(c *cli.Context) (err error) { // address must be passed func (s *Shell) ExportETHKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the address of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the address of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(newPassword) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } address := c.Args().Get(0) @@ -334,11 +334,11 @@ func (s *Shell) ExportETHKey(c *cli.Context) (err error) { exportUrl.RawQuery = query.Encode() resp, err := s.HTTP.Post(s.ctx(), exportUrl.String(), nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -348,12 +348,12 @@ func (s *Shell) ExportETHKey(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString("🔑 Exported ETH key " + address + " to " + filepath + "\n") @@ -377,7 +377,7 @@ func (s *Shell) UpdateChainEVMKey(c *cli.Context) (err error) { query.Set("abandon", abandon) if c.IsSet("enable") && c.IsSet("disable") { - return s.errorOut(errors.New("cannot set both --enable and --disable simultaneously")) + return s.errorOut(pkgerrors.New("cannot set both --enable and --disable simultaneously")) } else if c.Bool("enable") { query.Set("enabled", "true") } else if c.Bool("disable") { @@ -387,11 +387,11 @@ func (s *Shell) UpdateChainEVMKey(c *cli.Context) (err error) { chainURL.RawQuery = query.Encode() resp, err := s.HTTP.Post(s.ctx(), chainURL.String(), nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/evm_transaction_commands.go b/core/cmd/evm_transaction_commands.go index e1611021439..efd36c32a92 100644 --- a/core/cmd/evm_transaction_commands.go +++ b/core/cmd/evm_transaction_commands.go @@ -8,7 +8,6 @@ import ( "math/big" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -123,7 +122,7 @@ func (s *Shell) ShowTransaction(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -204,7 +203,7 @@ func (s *Shell) SendEther(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/forwarders_commands.go b/core/cmd/forwarders_commands.go index 2445be5bfec..ed63f3ba143 100644 --- a/core/cmd/forwarders_commands.go +++ b/core/cmd/forwarders_commands.go @@ -3,6 +3,7 @@ package cmd import ( "bytes" "encoding/json" + "errors" "fmt" "io" "math/big" @@ -10,9 +11,8 @@ import ( gethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/web" @@ -100,7 +100,7 @@ func (s *Shell) ListForwarders(c *cli.Context) (err error) { // DeleteForwarder deletes forwarder address from node db by id. func (s *Shell) DeleteForwarder(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("must pass the forwarder id to be archived")) + return s.errorOut(pkgerrors.New("must pass the forwarder id to be archived")) } resp, err := s.HTTP.Delete(s.ctx(), "/v2/nodes/evm/forwarders/"+c.Args().First()) if err != nil { @@ -122,7 +122,7 @@ func (s *Shell) TrackForwarder(c *cli.Context) (err error) { addressBytes, err := hexutil.Decode(addressHex) if err != nil { - return s.errorOut(errors.Wrap(err, "could not decode address")) + return s.errorOut(pkgerrors.Wrap(err, "could not decode address")) } address := gethCommon.BytesToAddress(addressBytes) @@ -131,7 +131,7 @@ func (s *Shell) TrackForwarder(c *cli.Context) (err error) { var ok bool chainID, ok = big.NewInt(0).SetString(chainIDStr, 10) if !ok { - return s.errorOut(errors.Wrap(err, "invalid evm-chain-id")) + return s.errorOut(pkgerrors.Wrap(err, "invalid evm-chain-id")) } } @@ -149,14 +149,14 @@ func (s *Shell) TrackForwarder(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() if resp.StatusCode >= 400 { body, rerr := io.ReadAll(resp.Body) if err != nil { - err = multierr.Append(err, rerr) + err = errors.Join(err, rerr) return s.errorOut(err) } fmt.Printf("Response: '%v', Status: %d\n", string(body), resp.StatusCode) diff --git a/core/cmd/jobs_commands.go b/core/cmd/jobs_commands.go index 1f9ca33c78e..4e98b3b03fa 100644 --- a/core/cmd/jobs_commands.go +++ b/core/cmd/jobs_commands.go @@ -3,14 +3,14 @@ package cmd import ( "bytes" "encoding/json" + "errors" "fmt" "io" "strings" "time" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/web" @@ -209,7 +209,7 @@ func (s *Shell) ListJobs(c *cli.Context) (err error) { // ShowJob displays the details of a job func (s *Shell) ShowJob(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("must provide the id of the job")) + return s.errorOut(pkgerrors.New("must provide the id of the job")) } id := c.Args().First() resp, err := s.HTTP.Get(s.ctx(), "/v2/jobs/"+id) @@ -218,7 +218,7 @@ func (s *Shell) ShowJob(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -229,7 +229,7 @@ func (s *Shell) ShowJob(c *cli.Context) (err error) { // Valid input is a TOML string or a path to TOML file func (s *Shell) CreateJob(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("must pass in TOML or filepath")) + return s.errorOut(pkgerrors.New("must pass in TOML or filepath")) } tomlString, err := getTOMLString(c.Args().First()) @@ -250,14 +250,14 @@ func (s *Shell) CreateJob(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() if resp.StatusCode >= 400 { body, rerr := io.ReadAll(resp.Body) if err != nil { - err = multierr.Append(err, rerr) + err = errors.Join(err, rerr) return s.errorOut(err) } fmt.Printf("Response: '%v', Status: %d\n", string(body), resp.StatusCode) @@ -271,7 +271,7 @@ func (s *Shell) CreateJob(c *cli.Context) (err error) { // DeleteJob deletes a job func (s *Shell) DeleteJob(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("must pass the job id to be archived")) + return s.errorOut(pkgerrors.New("must pass the job id to be archived")) } resp, err := s.HTTP.Delete(s.ctx(), "/v2/jobs/"+c.Args().First()) if err != nil { @@ -289,7 +289,7 @@ func (s *Shell) DeleteJob(c *cli.Context) error { // TriggerPipelineRun triggers a job run based on a job ID func (s *Shell) TriggerPipelineRun(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the job id to trigger a run")) + return s.errorOut(pkgerrors.New("Must pass the job id to trigger a run")) } resp, err := s.HTTP.Post(s.ctx(), "/v2/jobs/"+c.Args().First()+"/runs", nil) if err != nil { @@ -297,7 +297,7 @@ func (s *Shell) TriggerPipelineRun(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/keys_commands.go b/core/cmd/keys_commands.go index 7408d168887..fe4419a11b5 100644 --- a/core/cmd/keys_commands.go +++ b/core/cmd/keys_commands.go @@ -2,15 +2,15 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "os" "strings" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -111,7 +111,7 @@ func (cli *keysClient[K, P, P2]) ListKeys(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -127,7 +127,7 @@ func (cli *keysClient[K, P, P2]) CreateKey(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -139,7 +139,7 @@ func (cli *keysClient[K, P, P2]) CreateKey(_ *cli.Context) (err error) { // key ID must be passed func (cli *keysClient[K, P, P2]) DeleteKey(c *cli.Context) (err error) { if !c.Args().Present() { - return cli.errorOut(errors.New("Must pass the key ID to be deleted")) + return cli.errorOut(pkgerrors.New("Must pass the key ID to be deleted")) } id := c.Args().Get(0) @@ -158,7 +158,7 @@ func (cli *keysClient[K, P, P2]) DeleteKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -170,16 +170,16 @@ func (cli *keysClient[K, P, P2]) DeleteKey(c *cli.Context) (err error) { // path to key must be passed func (cli *keysClient[K, P, P2]) ImportKey(c *cli.Context) (err error) { if !c.Args().Present() { - return cli.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return cli.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return cli.errorOut(errors.New("Must specify --old-password/-p flag")) + return cli.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return cli.errorOut(errors.Wrap(err, "Could not read password file")) + return cli.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -195,7 +195,7 @@ func (cli *keysClient[K, P, P2]) ImportKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -207,21 +207,21 @@ func (cli *keysClient[K, P, P2]) ImportKey(c *cli.Context) (err error) { // key ID must be passed func (cli *keysClient[K, P, P2]) ExportKey(c *cli.Context) (err error) { if !c.Args().Present() { - return cli.errorOut(errors.New("Must pass the ID of the key to export")) + return cli.errorOut(pkgerrors.New("Must pass the ID of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return cli.errorOut(errors.New("Must specify --new-password/-p flag")) + return cli.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return cli.errorOut(errors.Wrap(err, "Could not read password file")) + return cli.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return cli.errorOut(errors.New("Must specify --output/-o flag")) + return cli.errorOut(pkgerrors.New("Must specify --output/-o flag")) } ID := c.Args().Get(0) @@ -229,11 +229,11 @@ func (cli *keysClient[K, P, P2]) ExportKey(c *cli.Context) (err error) { normalizedPassword := normalizePassword(string(newPassword)) resp, err := cli.HTTP.Post(cli.ctx(), cli.path+"/export/"+ID+"?newpassword="+normalizedPassword, nil) if err != nil { - return cli.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return cli.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -243,12 +243,12 @@ func (cli *keysClient[K, P, P2]) ExportKey(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return cli.errorOut(errors.Wrap(err, "Could not read response body")) + return cli.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0600) if err != nil { - return cli.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return cli.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("🔑 Exported %s key %s to %s\n", cli.typ, ID, filepath)) diff --git a/core/cmd/ocr2_keys_commands.go b/core/cmd/ocr2_keys_commands.go index 1d469024878..eb0e4b625e2 100644 --- a/core/cmd/ocr2_keys_commands.go +++ b/core/cmd/ocr2_keys_commands.go @@ -2,14 +2,14 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "os" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" @@ -133,7 +133,7 @@ func (s *Shell) ListOCR2KeyBundles(_ *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -145,7 +145,7 @@ func (s *Shell) ListOCR2KeyBundles(_ *cli.Context) error { func (s *Shell) CreateOCR2KeyBundle(c *cli.Context) error { if !c.Args().Present() { return s.errorOut( - errors.Errorf(`must pass the type to create, options are: %s`, chaintype.SupportedChainTypes.String()), + pkgerrors.Errorf(`must pass the type to create, options are: %s`, chaintype.SupportedChainTypes.String()), ) } chainType := c.Args().Get(0) @@ -155,7 +155,7 @@ func (s *Shell) CreateOCR2KeyBundle(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -166,7 +166,7 @@ func (s *Shell) CreateOCR2KeyBundle(c *cli.Context) error { // DeleteOCR2KeyBundle deletes an OCR2 key bundle func (s *Shell) DeleteOCR2KeyBundle(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the key ID to be deleted")) + return s.errorOut(pkgerrors.New("Must pass the key ID to be deleted")) } id, err := models.Sha256HashFromHex(c.Args().Get(0)) if err != nil { @@ -188,7 +188,7 @@ func (s *Shell) DeleteOCR2KeyBundle(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -199,16 +199,16 @@ func (s *Shell) DeleteOCR2KeyBundle(c *cli.Context) error { // ImportOCR2Key imports OCR2 key bundle func (s *Shell) ImportOCR2Key(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -224,7 +224,7 @@ func (s *Shell) ImportOCR2Key(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -235,21 +235,21 @@ func (s *Shell) ImportOCR2Key(c *cli.Context) (err error) { // ExportOCR2Key exports an OCR2 key bundle by ID func (s *Shell) ExportOCR2Key(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the ID of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the ID of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } ID := c.Args().Get(0) @@ -257,11 +257,11 @@ func (s *Shell) ExportOCR2Key(c *cli.Context) (err error) { normalizedPassword := normalizePassword(string(newPassword)) resp, err := s.HTTP.Post(s.ctx(), "/v2/keys/ocr2/export/"+ID+"?newpassword="+normalizedPassword, nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -271,12 +271,12 @@ func (s *Shell) ExportOCR2Key(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("Exported OCR key bundle %s to %s", ID, filepath)) diff --git a/core/cmd/ocr_keys_commands.go b/core/cmd/ocr_keys_commands.go index 399333bba93..0c47b62d6ce 100644 --- a/core/cmd/ocr_keys_commands.go +++ b/core/cmd/ocr_keys_commands.go @@ -2,14 +2,14 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "os" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -114,7 +114,7 @@ func (s *Shell) ListOCRKeyBundles(_ *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -147,7 +147,7 @@ func (s *Shell) CreateOCRKeyBundle(_ *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -158,7 +158,7 @@ func (s *Shell) CreateOCRKeyBundle(_ *cli.Context) error { // DeleteOCR2KeyBundle deletes an OCR key bundle func (s *Shell) DeleteOCRKeyBundle(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the key ID to be deleted")) + return s.errorOut(pkgerrors.New("Must pass the key ID to be deleted")) } id, err := models.Sha256HashFromHex(c.Args().Get(0)) if err != nil { @@ -180,7 +180,7 @@ func (s *Shell) DeleteOCRKeyBundle(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -191,16 +191,16 @@ func (s *Shell) DeleteOCRKeyBundle(c *cli.Context) error { // ImportOCR2Key imports OCR key bundle func (s *Shell) ImportOCRKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -216,7 +216,7 @@ func (s *Shell) ImportOCRKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -227,21 +227,21 @@ func (s *Shell) ImportOCRKey(c *cli.Context) (err error) { // ExportOCR2Key exports an OCR key bundle by ID func (s *Shell) ExportOCRKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the ID of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the ID of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } ID := c.Args().Get(0) @@ -249,11 +249,11 @@ func (s *Shell) ExportOCRKey(c *cli.Context) (err error) { normalizedPassword := normalizePassword(string(newPassword)) resp, err := s.HTTP.Post(s.ctx(), "/v2/keys/ocr/export/"+ID+"?newpassword="+normalizedPassword, nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -263,12 +263,12 @@ func (s *Shell) ExportOCRKey(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("Exported OCR key bundle %s to %s", ID, filepath)) diff --git a/core/cmd/p2p_keys_commands.go b/core/cmd/p2p_keys_commands.go index da3bf412a04..001202269dc 100644 --- a/core/cmd/p2p_keys_commands.go +++ b/core/cmd/p2p_keys_commands.go @@ -2,14 +2,14 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "os" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -131,7 +131,7 @@ func (s *Shell) ListP2PKeys(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -146,7 +146,7 @@ func (s *Shell) CreateP2PKey(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -157,7 +157,7 @@ func (s *Shell) CreateP2PKey(_ *cli.Context) (err error) { // key ID must be passed func (s *Shell) DeleteP2PKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the key ID to be deleted")) + return s.errorOut(pkgerrors.New("Must pass the key ID to be deleted")) } id := c.Args().Get(0) @@ -176,7 +176,7 @@ func (s *Shell) DeleteP2PKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -187,16 +187,16 @@ func (s *Shell) DeleteP2PKey(c *cli.Context) (err error) { // path to key must be passed func (s *Shell) ImportP2PKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -212,7 +212,7 @@ func (s *Shell) ImportP2PKey(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -223,21 +223,21 @@ func (s *Shell) ImportP2PKey(c *cli.Context) (err error) { // key ID must be passed func (s *Shell) ExportP2PKey(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the ID of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the ID of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } ID := c.Args().Get(0) @@ -245,11 +245,11 @@ func (s *Shell) ExportP2PKey(c *cli.Context) (err error) { normalizedPassword := normalizePassword(string(newPassword)) resp, err := s.HTTP.Post(s.ctx(), "/v2/keys/p2p/export/"+ID+"?newpassword="+normalizedPassword, nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -259,12 +259,12 @@ func (s *Shell) ExportP2PKey(c *cli.Context) (err error) { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("🔑 Exported P2P key %s to %s\n", ID, filepath)) diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 05081cdc314..7caa038548a 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -27,7 +27,6 @@ import ( "github.com/gin-gonic/gin" pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "go.uber.org/zap/zapcore" "golang.org/x/sync/errgroup" @@ -714,7 +713,7 @@ func (d DiskCookieStore) Retrieve() (*http.Cookie, error) { if os.IsNotExist(err) { return nil, nil } - return nil, multierr.Append(errors.New("unable to retrieve credentials, you must first login through the CLI"), err) + return nil, errors.Join(errors.New("unable to retrieve credentials, you must first login through the CLI"), err) } header := http.Header{} header.Add("Cookie", string(b)) diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index b970b516413..625afb52b99 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -4,6 +4,7 @@ import ( "context" crand "crypto/rand" "database/sql" + "errors" "fmt" "log" "math/big" @@ -25,9 +26,8 @@ import ( "github.com/lib/pq" "github.com/kylelemons/godebug/diff" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "golang.org/x/sync/errgroup" "gopkg.in/guregu/null.v4" @@ -54,7 +54,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/internal/testdb" ) -var ErrProfileTooLong = errors.New("requested profile duration too large") +var ErrProfileTooLong = pkgerrors.New("requested profile duration too large") func initLocalSubCmds(s *Shell, safe bool) []cli.Command { return []cli.Command{ @@ -274,14 +274,14 @@ func (s *Shell) runNode(c *cli.Context) error { if passwordFile := c.String("password"); passwordFile != "" { p, err := utils.PasswordFromFile(passwordFile) if err != nil { - return errors.Wrap(err, "error reading password from file") + return pkgerrors.Wrap(err, "error reading password from file") } pwd = &p } if vrfPasswordFile := c.String("vrfpassword"); len(vrfPasswordFile) != 0 { p, err := utils.PasswordFromFile(vrfPasswordFile) if err != nil { - return errors.Wrapf(err, "error reading VRF password from vrfpassword file \"%s\"", vrfPasswordFile) + return pkgerrors.Wrapf(err, "error reading VRF password from vrfpassword file \"%s\"", vrfPasswordFile) } vrfpwd = &p } @@ -291,7 +291,7 @@ func (s *Shell) runNode(c *cli.Context) error { s.Config.LogConfiguration(lggr.Debugf, lggr.Warnf) if err := s.Config.Validate(); err != nil { - return errors.Wrap(err, "config validation failed") + return pkgerrors.Wrap(err, "config validation failed") } lggr.Infow(fmt.Sprintf("Starting Chainlink Node %s at commit %s", static.Version, static.Sha), "Version", static.Version, "SHA", static.Sha) @@ -348,7 +348,7 @@ func (s *Shell) runNode(c *cli.Context) error { // Try opening DB connection and acquiring DB locks at once if err := ldb.Open(rootCtx); err != nil { // If not successful, we know neither locks nor connection remains opened - return s.errorOut(errors.Wrap(err, "opening db")) + return s.errorOut(pkgerrors.Wrap(err, "opening db")) } defer lggr.ErrorIfFn(ldb.Close, "Error closing db") @@ -357,7 +357,7 @@ func (s *Shell) runNode(c *cli.Context) error { app, err := s.AppFactory.NewApplication(rootCtx, s.Config, s.Logger, ldb.DB()) if err != nil { - return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) + return s.errorOut(pkgerrors.Wrap(err, "fatal error instantiating application")) } // Local shell initialization always uses local auth users table for admin auth @@ -365,7 +365,7 @@ func (s *Shell) runNode(c *cli.Context) error { keyStore := app.GetKeyStore() err = s.KeyStoreAuthenticator.authenticate(keyStore, s.Config.Password()) if err != nil { - return errors.Wrap(err, "error authenticating keystore") + return pkgerrors.Wrap(err, "error authenticating keystore") } legacyEVMChains := app.GetRelayers().LegacyEVMChains() @@ -380,7 +380,7 @@ func (s *Shell) runNode(c *cli.Context) error { lggr.Debugf("AutoCreateKey=true, will ensure EVM key for chain %s", ch.ID()) err2 := app.GetKeyStore().Eth().EnsureKeys(ch.ID()) if err2 != nil { - return errors.Wrap(err2, "failed to ensure keystore keys") + return pkgerrors.Wrap(err2, "failed to ensure keystore keys") } } else { lggr.Debugf("AutoCreateKey=false, will not ensure EVM key for chain %s", ch.ID()) @@ -391,7 +391,7 @@ func (s *Shell) runNode(c *cli.Context) error { if s.Config.OCR().Enabled() { err2 := app.GetKeyStore().OCR().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure ocr key") + return pkgerrors.Wrap(err2, "failed to ensure ocr key") } } if s.Config.OCR2().Enabled() { @@ -410,37 +410,37 @@ func (s *Shell) runNode(c *cli.Context) error { } err2 := app.GetKeyStore().OCR2().EnsureKeys(enabledChains...) if err2 != nil { - return errors.Wrap(err2, "failed to ensure ocr key") + return pkgerrors.Wrap(err2, "failed to ensure ocr key") } } if s.Config.P2P().Enabled() { err2 := app.GetKeyStore().P2P().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure p2p key") + return pkgerrors.Wrap(err2, "failed to ensure p2p key") } } if s.Config.CosmosEnabled() { err2 := app.GetKeyStore().Cosmos().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure cosmos key") + return pkgerrors.Wrap(err2, "failed to ensure cosmos key") } } if s.Config.SolanaEnabled() { err2 := app.GetKeyStore().Solana().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure solana key") + return pkgerrors.Wrap(err2, "failed to ensure solana key") } } if s.Config.StarkNetEnabled() { err2 := app.GetKeyStore().StarkNet().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure starknet key") + return pkgerrors.Wrap(err2, "failed to ensure starknet key") } } err2 := app.GetKeyStore().CSA().EnsureKey() if err2 != nil { - return errors.Wrap(err2, "failed to ensure CSA key") + return pkgerrors.Wrap(err2, "failed to ensure CSA key") } if e := checkFilePermissions(lggr, s.Config.RootDir()); e != nil { @@ -449,14 +449,14 @@ func (s *Shell) runNode(c *cli.Context) error { var user sessions.User if user, err = NewFileAPIInitializer(c.String("api")).Initialize(authProviderORM, lggr); err != nil { - if !errors.Is(err, ErrNoCredentialFile) { - return errors.Wrap(err, "error creating api initializer") + if !pkgerrors.Is(err, ErrNoCredentialFile) { + return pkgerrors.Wrap(err, "error creating api initializer") } if user, err = s.FallbackAPIInitializer.Initialize(authProviderORM, lggr); err != nil { - if errors.Is(err, ErrorNoAPICredentialsAvailable) { - return errors.WithStack(err) + if pkgerrors.Is(err, ErrorNoAPICredentialsAvailable) { + return pkgerrors.WithStack(err) } - return errors.Wrap(err, "error creating fallback initializer") + return pkgerrors.Wrap(err, "error creating fallback initializer") } } @@ -466,7 +466,7 @@ func (s *Shell) runNode(c *cli.Context) error { // We do not try stopping any sub-services that might be started, // because the app will exit immediately upon return. // But LockedDB will be released by defer in above. - return errors.Wrap(err, "error starting app") + return pkgerrors.Wrap(err, "error starting app") } grp, grpCtx := errgroup.WithContext(rootCtx) @@ -474,7 +474,7 @@ func (s *Shell) runNode(c *cli.Context) error { grp.Go(func() error { <-grpCtx.Done() if errInternal := app.Stop(); errInternal != nil { - return errors.Wrap(errInternal, "error stopping app") + return pkgerrors.Wrap(errInternal, "error stopping app") } return nil }) @@ -483,7 +483,7 @@ func (s *Shell) runNode(c *cli.Context) error { grp.Go(func() error { errInternal := s.Runner.Run(grpCtx, app) - if errors.Is(errInternal, http.ErrServerClosed) { + if pkgerrors.Is(errInternal, http.ErrServerClosed) { errInternal = nil } // In tests we have custom runners that stop the app gracefully, @@ -566,7 +566,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { addressBytes, err := hexutil.Decode(addressHex) if err != nil { - return s.errorOut(errors.Wrap(err, "could not decode address")) + return s.errorOut(pkgerrors.Wrap(err, "could not decode address")) } address := gethCommon.BytesToAddress(addressBytes) @@ -575,20 +575,20 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { var ok bool chainID, ok = big.NewInt(0).SetString(chainIDStr, 10) if !ok { - return s.errorOut(errors.New("invalid evmChainID")) + return s.errorOut(pkgerrors.New("invalid evmChainID")) } } lggr := logger.Sugared(s.Logger.Named("RebroadcastTransactions")) db, err := pg.OpenUnlockedDB(s.Config.AppID(), s.Config.Database()) if err != nil { - return s.errorOut(errors.Wrap(err, "opening DB")) + return s.errorOut(pkgerrors.Wrap(err, "opening DB")) } defer lggr.ErrorIfFn(db.Close, "Error closing db") app, err := s.AppFactory.NewApplication(ctx, s.Config, lggr, db) if err != nil { - return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) + return s.errorOut(pkgerrors.Wrap(err, "fatal error instantiating application")) } // TODO: BCF-2511 once the dust settles on BCF-2440/1 evaluate how the @@ -622,7 +622,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { err = keyStore.Unlock(s.Config.Password().Keystore()) if err != nil { - return s.errorOut(errors.Wrap(err, "error authenticating keystore")) + return s.errorOut(pkgerrors.Wrap(err, "error authenticating keystore")) } if err = keyStore.Eth().CheckEnabled(address, chain.ID()); err != nil { @@ -685,7 +685,7 @@ func (ps HealthCheckPresenters) RenderTable(rt RendererTable) error { return nil } -var errDBURLMissing = errors.New("You must set CL_DATABASE_URL env variable or provide a secrets TOML with Database.URL set. HINT: If you are running this to set up your local test database, try CL_DATABASE_URL=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable") +var errDBURLMissing = pkgerrors.New("You must set CL_DATABASE_URL env variable or provide a secrets TOML with Database.URL set. HINT: If you are running this to set up your local test database, try CL_DATABASE_URL=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable") // ConfigValidate validate the client configuration and pretty-prints results func (s *Shell) ConfigFileValidate(_ *cli.Context) error { @@ -817,7 +817,7 @@ func dropDanglingTestDBs(lggr logger.Logger, db *sqlx.DB) (err error) { wg.Wait() close(errCh) for gerr := range errCh { - err = multierr.Append(err, gerr) + err = errors.Join(err, gerr) } return } @@ -911,7 +911,7 @@ func (s *Shell) RollbackDatabase(c *cli.Context) error { arg := c.Args().First() numVersion, err := strconv.ParseInt(arg, 10, 64) if err != nil { - return s.errorOut(errors.Errorf("Unable to parse %v as integer", arg)) + return s.errorOut(pkgerrors.Errorf("Unable to parse %v as integer", arg)) } version = null.IntFrom(numVersion) } @@ -962,7 +962,7 @@ func (s *Shell) StatusDatabase(_ *cli.Context) error { // CreateMigration displays the database migration status func (s *Shell) CreateMigration(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("You must specify a migration name")) + return s.errorOut(pkgerrors.New("You must specify a migration name")) } db, err := newConnection(s.Config.Database()) if err != nil { @@ -995,7 +995,7 @@ func (s *Shell) CleanupChainTables(c *cli.Context) error { db, err := newConnection(cfg) if err != nil { - return s.errorOut(errors.Wrap(err, "error connecting to the database")) + return s.errorOut(pkgerrors.Wrap(err, "error connecting to the database")) } defer db.Close() @@ -1032,7 +1032,7 @@ func (s *Shell) CleanupChainTables(c *cli.Context) error { } } } else { - return s.errorOut(errors.New("unknown chain type")) + return s.errorOut(pkgerrors.New("unknown chain type")) } return nil } @@ -1065,7 +1065,7 @@ func dropAndCreateDB(parsed url.URL) (err error) { } defer func() { if cerr := db.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -1130,7 +1130,7 @@ func dumpSchema(dbURL url.URL) (string, error) { schema, err := cmd.Output() if err != nil { var ee *exec.ExitError - if errors.As(err, &ee) { + if pkgerrors.As(err, &ee) { return "", fmt.Errorf("failed to dump schema: %v\n%s", err, string(ee.Stderr)) } return "", fmt.Errorf("failed to dump schema: %v", err) @@ -1146,7 +1146,7 @@ func checkSchema(dbURL url.URL, prevSchema string) error { df := diff.Diff(prevSchema, newSchema) if len(df) > 0 { fmt.Println(df) - return errors.New("schema pre- and post- rollback does not match (ctrl+f for '+' or '-' to find the changed lines)") + return pkgerrors.New("schema pre- and post- rollback does not match (ctrl+f for '+' or '-' to find the changed lines)") } return nil } @@ -1158,13 +1158,13 @@ func insertFixtures(dbURL url.URL, pathToFixtures string) (err error) { } defer func() { if cerr := db.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() _, filename, _, ok := runtime.Caller(1) if !ok { - return errors.New("could not get runtime.Caller(1)") + return pkgerrors.New("could not get runtime.Caller(1)") } filepath := path.Join(path.Dir(filename), pathToFixtures) fixturesSQL, err := os.ReadFile(filepath) diff --git a/core/cmd/shell_remote.go b/core/cmd/shell_remote.go index aab4a94da6f..37a28ea53a5 100644 --- a/core/cmd/shell_remote.go +++ b/core/cmd/shell_remote.go @@ -3,6 +3,7 @@ package cmd import ( "bytes" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -15,10 +16,9 @@ import ( "github.com/manyminds/api2go/jsonapi" "github.com/mitchellh/go-homedir" "github.com/pelletier/go-toml" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/tidwall/gjson" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -80,15 +80,15 @@ func initRemoteConfigSubCmds(s *Shell) []cli.Command { } var ( - errUnauthorized = errors.New(http.StatusText(http.StatusUnauthorized)) - errForbidden = errors.New(http.StatusText(http.StatusForbidden)) - errBadRequest = errors.New(http.StatusText(http.StatusBadRequest)) + errUnauthorized = pkgerrors.New(http.StatusText(http.StatusUnauthorized)) + errForbidden = pkgerrors.New(http.StatusText(http.StatusForbidden)) + errBadRequest = pkgerrors.New(http.StatusText(http.StatusBadRequest)) ) // CreateExternalInitiator adds an external initiator func (s *Shell) CreateExternalInitiator(c *cli.Context) (err error) { if c.NArg() != 1 && c.NArg() != 2 { - return s.errorOut(errors.New("create expects 1 - 2 arguments: a name and a url (optional)")) + return s.errorOut(pkgerrors.New("create expects 1 - 2 arguments: a name and a url (optional)")) } var request bridges.ExternalInitiatorRequest @@ -116,7 +116,7 @@ func (s *Shell) CreateExternalInitiator(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -128,7 +128,7 @@ func (s *Shell) CreateExternalInitiator(c *cli.Context) (err error) { // DeleteExternalInitiator removes an external initiator func (s *Shell) DeleteExternalInitiator(c *cli.Context) (err error) { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the name of the external initiator to delete")) + return s.errorOut(pkgerrors.New("Must pass the name of the external initiator to delete")) } resp, err := s.HTTP.Delete(s.ctx(), "/v2/external_initiators/"+c.Args().First()) @@ -137,7 +137,7 @@ func (s *Shell) DeleteExternalInitiator(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() _, err = s.parseResponse(resp) @@ -161,7 +161,7 @@ func (s *Shell) getPage(requestURI string, page int, model interface{}) (err err } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -200,7 +200,7 @@ func (s *Shell) Logout(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() err = s.CookieAuthenticator.Logout() @@ -230,7 +230,7 @@ func (s *Shell) ChangePassword(_ *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -270,12 +270,12 @@ func getTOMLString(s string) (string, error) { func (s *Shell) parseResponse(resp *http.Response) ([]byte, error) { b, err := parseResponse(resp) - if errors.Is(err, errUnauthorized) { - return nil, s.errorOut(multierr.Append(err, fmt.Errorf("your credentials may be missing, invalid or you may need to login first using the CLI via 'chainlink admin login'"))) + if pkgerrors.Is(err, errUnauthorized) { + return nil, s.errorOut(errors.Join(err, fmt.Errorf("your credentials may be missing, invalid or you may need to login first using the CLI via 'chainlink admin login'"))) } - if errors.Is(err, errForbidden) { - return nil, s.errorOut(multierr.Append(err, fmt.Errorf("this action requires %s privileges. The current user %s has '%s' role and cannot perform this action, login with a user that has '%s' role via 'chainlink admin login'", resp.Header.Get("forbidden-required-role"), resp.Header.Get("forbidden-provided-email"), resp.Header.Get("forbidden-provided-role"), resp.Header.Get("forbidden-required-role")))) + if pkgerrors.Is(err, errForbidden) { + return nil, s.errorOut(errors.Join(err, fmt.Errorf("this action requires %s privileges. The current user %s has '%s' role and cannot perform this action, login with a user that has '%s' role via 'chainlink admin login'", resp.Header.Get("forbidden-required-role"), resp.Header.Get("forbidden-provided-email"), resp.Header.Get("forbidden-provided-role"), resp.Header.Get("forbidden-required-role")))) } if err != nil { return nil, s.errorOut(err) @@ -319,7 +319,7 @@ func (s *Shell) configV2Str(userOnly bool) (string, error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() respPayload, err := io.ReadAll(resp.Body) @@ -327,7 +327,7 @@ func (s *Shell) configV2Str(userOnly bool) (string, error) { return "", s.errorOut(err) } if resp.StatusCode != 200 { - return "", s.errorOut(errors.Errorf("got HTTP status %d: %s", resp.StatusCode, respPayload)) + return "", s.errorOut(pkgerrors.Errorf("got HTTP status %d: %s", resp.StatusCode, respPayload)) } var configV2Resource web.ConfigV2Resource err = web.ParseJSONAPIResponse(respPayload, &configV2Resource) @@ -357,7 +357,7 @@ func (s *Shell) SetLogLevel(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -370,7 +370,7 @@ func (s *Shell) SetLogLevel(c *cli.Context) (err error) { func (s *Shell) SetLogSQL(c *cli.Context) (err error) { // Enforces selection of --enable or --disable if !c.Bool("enable") && !c.Bool("disable") { - return s.errorOut(errors.New("Must set logSql --enabled || --disable")) + return s.errorOut(pkgerrors.New("Must set logSql --enabled || --disable")) } // Sets logSql to true || false based on the --enabled flag @@ -389,7 +389,7 @@ func (s *Shell) SetLogSQL(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -428,7 +428,7 @@ func fromFile(arg string) (*bytes.Buffer, error) { func (s *Shell) deserializeAPIResponse(resp *http.Response, dst interface{}, links *jsonapi.Links) error { b, err := s.parseResponse(resp) if err != nil { - return errors.Wrap(err, "parseResponse error") + return pkgerrors.Wrap(err, "parseResponse error") } if err = web.ParsePaginatedResponse(b, dst, links); err != nil { return s.errorOut(err) @@ -442,15 +442,15 @@ func parseErrorResponseBody(responseBody []byte) (string, error) { return "Empty error message", nil } - var errors models.JSONAPIErrors - err := json.Unmarshal(responseBody, &errors) - if err != nil || len(errors.Errors) == 0 { + var errs models.JSONAPIErrors + err := json.Unmarshal(responseBody, &errs) + if err != nil || len(errs.Errors) == 0 { return "", err } var errorDetails strings.Builder - errorDetails.WriteString(errors.Errors[0].Detail) - for _, errorDetail := range errors.Errors[1:] { + errorDetails.WriteString(errs.Errors[0].Detail) + for _, errorDetail := range errs.Errors[1:] { fmt.Fprintf(&errorDetails, "\n%s", errorDetail.Detail) } return errorDetails.String(), nil @@ -459,7 +459,7 @@ func parseErrorResponseBody(responseBody []byte) (string, error) { func parseResponse(resp *http.Response) ([]byte, error) { b, err := io.ReadAll(resp.Body) if err != nil { - return b, multierr.Append(errors.New(resp.Status), err) + return b, errors.Join(pkgerrors.New(resp.Status), err) } if resp.StatusCode == http.StatusUnauthorized { return b, errUnauthorized @@ -470,7 +470,7 @@ func parseResponse(resp *http.Response) ([]byte, error) { if err2 != nil { return b, err2 } - return b, errors.New(errorMessage) + return b, pkgerrors.New(errorMessage) } return b, err } diff --git a/core/cmd/solana_transaction_commands.go b/core/cmd/solana_transaction_commands.go index 7eaac7930a2..688cfa977c1 100644 --- a/core/cmd/solana_transaction_commands.go +++ b/core/cmd/solana_transaction_commands.go @@ -10,7 +10,6 @@ import ( solanaGo "github.com/gagliardetto/solana-go" pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/store/models/solana" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" @@ -112,7 +111,7 @@ func (s *Shell) SolanaSendSol(c *cli.Context) (err error) { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/cmd/vrf_keys_commands.go b/core/cmd/vrf_keys_commands.go index 32d32334af5..ab1f17c3b38 100644 --- a/core/cmd/vrf_keys_commands.go +++ b/core/cmd/vrf_keys_commands.go @@ -2,14 +2,14 @@ package cmd import ( "bytes" + "errors" "fmt" "io" "net/http" "os" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/urfave/cli" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -124,7 +124,7 @@ func (s *Shell) CreateVRFKey(_ *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -135,16 +135,16 @@ func (s *Shell) CreateVRFKey(_ *cli.Context) error { // ImportVRFKey reads a file into an EncryptedVRFKey in the db func (s *Shell) ImportVRFKey(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the filepath of the key to be imported")) + return s.errorOut(pkgerrors.New("Must pass the filepath of the key to be imported")) } oldPasswordFile := c.String("old-password") if len(oldPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --old-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --old-password/-p flag")) } oldPassword, err := os.ReadFile(oldPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.Args().Get(0) @@ -160,7 +160,7 @@ func (s *Shell) ImportVRFKey(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -172,21 +172,21 @@ func (s *Shell) ImportVRFKey(c *cli.Context) error { // requested file path. func (s *Shell) ExportVRFKey(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the ID (compressed public key) of the key to export")) + return s.errorOut(pkgerrors.New("Must pass the ID (compressed public key) of the key to export")) } newPasswordFile := c.String("new-password") if len(newPasswordFile) == 0 { - return s.errorOut(errors.New("Must specify --new-password/-p flag")) + return s.errorOut(pkgerrors.New("Must specify --new-password/-p flag")) } newPassword, err := os.ReadFile(newPasswordFile) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read password file")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read password file")) } filepath := c.String("output") if len(filepath) == 0 { - return s.errorOut(errors.New("Must specify --output/-o flag")) + return s.errorOut(pkgerrors.New("Must specify --output/-o flag")) } pk, err := getPublicKey(c) @@ -197,11 +197,11 @@ func (s *Shell) ExportVRFKey(c *cli.Context) error { normalizedPassword := normalizePassword(string(newPassword)) resp, err := s.HTTP.Post(s.ctx(), "/v2/keys/vrf/export/"+pk.String()+"?newpassword="+normalizedPassword, nil) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not make HTTP request")) + return s.errorOut(pkgerrors.Wrap(err, "Could not make HTTP request")) } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -211,12 +211,12 @@ func (s *Shell) ExportVRFKey(c *cli.Context) error { keyJSON, err := io.ReadAll(resp.Body) if err != nil { - return s.errorOut(errors.Wrap(err, "Could not read response body")) + return s.errorOut(pkgerrors.Wrap(err, "Could not read response body")) } err = utils.WriteFileWithMaxPerms(filepath, keyJSON, 0o600) if err != nil { - return s.errorOut(errors.Wrapf(err, "Could not write %v", filepath)) + return s.errorOut(pkgerrors.Wrapf(err, "Could not write %v", filepath)) } _, err = os.Stderr.WriteString(fmt.Sprintf("Exported VRF key %s to %s\n", pk.String(), filepath)) @@ -232,7 +232,7 @@ func (s *Shell) ExportVRFKey(c *cli.Context) error { // (no such protection for the V1 jobs exists). func (s *Shell) DeleteVRFKey(c *cli.Context) error { if !c.Args().Present() { - return s.errorOut(errors.New("Must pass the key ID (compressed public key) to be deleted")) + return s.errorOut(pkgerrors.New("Must pass the key ID (compressed public key) to be deleted")) } id, err := getPublicKey(c) if err != nil { @@ -254,7 +254,7 @@ func (s *Shell) DeleteVRFKey(c *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() @@ -269,7 +269,7 @@ func getPublicKey(c *cli.Context) (secp256k1.PublicKey, error) { } publicKey, err := secp256k1.NewPublicKeyFromHex(pkHexString) if err != nil { - return secp256k1.PublicKey{}, errors.Wrap(err, "failed to parse public key") + return secp256k1.PublicKey{}, pkgerrors.Wrap(err, "failed to parse public key") } return publicKey, nil } @@ -282,7 +282,7 @@ func (s *Shell) ListVRFKeys(_ *cli.Context) error { } defer func() { if cerr := resp.Body.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() diff --git a/core/config/docs/docs.go b/core/config/docs/docs.go index df082465036..7c4fd0e3ff5 100644 --- a/core/config/docs/docs.go +++ b/core/config/docs/docs.go @@ -2,12 +2,11 @@ package docs import ( _ "embed" + "errors" "fmt" "log" "strings" - "go.uber.org/multierr" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -251,12 +250,12 @@ func parseTOMLDocs(s string) (items []fmt.Stringer, err error) { kv.name = currentTable.name + "." + kv.name } if len(kv.desc) == 0 { - err = multierr.Append(err, fmt.Errorf("%s: missing description", kv.name)) + err = errors.Join(err, fmt.Errorf("%s: missing description", kv.name)) } else if !strings.HasPrefix(kv.desc[0], shortName) { - err = multierr.Append(err, fmt.Errorf("%s: description does not begin with %q", kv.name, shortName)) + err = errors.Join(err, fmt.Errorf("%s: description does not begin with %q", kv.name, shortName)) } if !strings.HasSuffix(line, fieldDefault) && !strings.HasSuffix(line, fieldExample) { - err = multierr.Append(err, fmt.Errorf(`%s: is not one of %v`, kv.name, []string{fieldDefault, fieldExample})) + err = errors.Join(err, fmt.Errorf(`%s: is not one of %v`, kv.name, []string{fieldDefault, fieldExample})) } items = append(items, kv) diff --git a/core/config/toml/types.go b/core/config/toml/types.go index eae5b2f533a..7df9bc2303d 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/google/uuid" - "go.uber.org/multierr" "go.uber.org/zap/zapcore" ocrcommontypes "github.com/smartcontractkit/libocr/commontypes" @@ -95,7 +94,7 @@ func (c *Core) SetFrom(f *Core) { func (c *Core) ValidateConfig() (err error) { _, verr := parse.HomeDir(*c.RootDir) if err != nil { - err = multierr.Append(err, configutils.ErrInvalid{Name: "RootDir", Value: true, Msg: fmt.Sprintf("Failed to expand RootDir. Please use an explicit path: %s", verr)}) + err = errors.Join(err, configutils.ErrInvalid{Name: "RootDir", Value: true, Msg: fmt.Sprintf("Failed to expand RootDir. Please use an explicit path: %s", verr)}) } return err @@ -152,17 +151,17 @@ func (d *DatabaseSecrets) ValidateConfig() (err error) { func (d *DatabaseSecrets) validateConfig(buildMode string) (err error) { if d.URL == nil || (*url.URL)(d.URL).String() == "" { - err = multierr.Append(err, configutils.ErrEmpty{Name: "URL", Msg: "must be provided and non-empty"}) + err = errors.Join(err, configutils.ErrEmpty{Name: "URL", Msg: "must be provided and non-empty"}) } else if *d.AllowSimplePasswords && buildMode == build.Prod { - err = multierr.Append(err, configutils.ErrInvalid{Name: "AllowSimplePasswords", Value: true, Msg: "insecure configs are not allowed on secure builds"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "AllowSimplePasswords", Value: true, Msg: "insecure configs are not allowed on secure builds"}) } else if !*d.AllowSimplePasswords { if verr := validateDBURL((url.URL)(*d.URL)); verr != nil { - err = multierr.Append(err, configutils.ErrInvalid{Name: "URL", Value: "*****", Msg: dbURLPasswordComplexity(verr)}) + err = errors.Join(err, configutils.ErrInvalid{Name: "URL", Value: "*****", Msg: dbURLPasswordComplexity(verr)}) } } if d.BackupURL != nil && !*d.AllowSimplePasswords { if verr := validateDBURL((url.URL)(*d.BackupURL)); verr != nil { - err = multierr.Append(err, configutils.ErrInvalid{Name: "BackupURL", Value: "*****", Msg: dbURLPasswordComplexity(verr)}) + err = errors.Join(err, configutils.ErrInvalid{Name: "BackupURL", Value: "*****", Msg: dbURLPasswordComplexity(verr)}) } } return err @@ -188,15 +187,15 @@ func (d *DatabaseSecrets) SetFrom(f *DatabaseSecrets) (err error) { func (d *DatabaseSecrets) validateMerge(f *DatabaseSecrets) (err error) { if d.AllowSimplePasswords != nil && f.AllowSimplePasswords != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "AllowSimplePasswords"}) + err = errors.Join(err, configutils.ErrOverride{Name: "AllowSimplePasswords"}) } if d.BackupURL != nil && f.BackupURL != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "BackupURL"}) + err = errors.Join(err, configutils.ErrOverride{Name: "BackupURL"}) } if d.URL != nil && f.URL != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "URL"}) + err = errors.Join(err, configutils.ErrOverride{Name: "URL"}) } return err @@ -225,11 +224,11 @@ func (p *Passwords) SetFrom(f *Passwords) (err error) { func (p *Passwords) validateMerge(f *Passwords) (err error) { if p.Keystore != nil && f.Keystore != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "Keystore"}) + err = errors.Join(err, configutils.ErrOverride{Name: "Keystore"}) } if p.VRF != nil && f.VRF != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "VRF"}) + err = errors.Join(err, configutils.ErrOverride{Name: "VRF"}) } return err @@ -237,7 +236,7 @@ func (p *Passwords) validateMerge(f *Passwords) (err error) { func (p *Passwords) ValidateConfig() (err error) { if p.Keystore == nil || *p.Keystore == "" { - err = multierr.Append(err, configutils.ErrEmpty{Name: "Keystore", Msg: "must be provided and non-empty"}) + err = errors.Join(err, configutils.ErrEmpty{Name: "Keystore", Msg: "must be provided and non-empty"}) } return err } @@ -261,7 +260,7 @@ func (p *PyroscopeSecrets) SetFrom(f *PyroscopeSecrets) (err error) { func (p *PyroscopeSecrets) validateMerge(f *PyroscopeSecrets) (err error) { if p.AuthToken != nil && f.AuthToken != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "AuthToken"}) + err = errors.Join(err, configutils.ErrOverride{Name: "AuthToken"}) } return err @@ -286,7 +285,7 @@ func (p *PrometheusSecrets) SetFrom(f *PrometheusSecrets) (err error) { func (p *PrometheusSecrets) validateMerge(f *PrometheusSecrets) (err error) { if p.AuthToken != nil && f.AuthToken != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "AuthToken"}) + err = errors.Join(err, configutils.ErrOverride{Name: "AuthToken"}) } return err @@ -386,7 +385,7 @@ func (l *DatabaseLock) Mode() string { func (l *DatabaseLock) ValidateConfig() (err error) { if l.LeaseRefreshInterval.Duration() > l.LeaseDuration.Duration()/2 { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LeaseRefreshInterval", Value: l.LeaseRefreshInterval.String(), + err = errors.Join(err, configutils.ErrInvalid{Name: "LeaseRefreshInterval", Value: l.LeaseRefreshInterval.String(), Msg: fmt.Sprintf("must be less than or equal to half of LeaseDuration (%s)", l.LeaseDuration.String())}) } return @@ -667,28 +666,28 @@ func (w *WebServer) ValidateConfig() (err error) { // Assert LDAP fields when AuthMethod set to LDAP if *w.LDAP.BaseDN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseDN", Msg: "LDAP BaseDN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.BaseDN", Msg: "LDAP BaseDN can not be empty"}) } if *w.LDAP.BaseUserAttr == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.BaseUserAttr", Msg: "LDAP BaseUserAttr can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.BaseUserAttr", Msg: "LDAP BaseUserAttr can not be empty"}) } if *w.LDAP.UsersDN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.UsersDN", Msg: "LDAP UsersDN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.UsersDN", Msg: "LDAP UsersDN can not be empty"}) } if *w.LDAP.GroupsDN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.GroupsDN", Msg: "LDAP GroupsDN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.GroupsDN", Msg: "LDAP GroupsDN can not be empty"}) } if *w.LDAP.AdminUserGroupCN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.AdminUserGroupCN", Msg: "LDAP AdminUserGroupCN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.AdminUserGroupCN", Msg: "LDAP AdminUserGroupCN can not be empty"}) } if *w.LDAP.EditUserGroupCN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) } if *w.LDAP.RunUserGroupCN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP RunUserGroupCN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.RunUserGroupCN", Msg: "LDAP RunUserGroupCN can not be empty"}) } if *w.LDAP.ReadUserGroupCN == "" { - err = multierr.Append(err, configutils.ErrInvalid{Name: "LDAP.ReadUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "LDAP.ReadUserGroupCN", Msg: "LDAP ReadUserGroupCN can not be empty"}) } return err } @@ -1257,17 +1256,17 @@ func (ins *Insecure) validateConfig(buildMode string) (err error) { return } if ins.DevWebServer != nil && *ins.DevWebServer { - err = multierr.Append(err, configutils.ErrInvalid{Name: "DevWebServer", Value: *ins.DevWebServer, Msg: "insecure configs are not allowed on secure builds"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "DevWebServer", Value: *ins.DevWebServer, Msg: "insecure configs are not allowed on secure builds"}) } // OCRDevelopmentMode is allowed on dev/test builds. if ins.OCRDevelopmentMode != nil && *ins.OCRDevelopmentMode && buildMode == build.Prod { - err = multierr.Append(err, configutils.ErrInvalid{Name: "OCRDevelopmentMode", Value: *ins.OCRDevelopmentMode, Msg: "insecure configs are not allowed on secure builds"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "OCRDevelopmentMode", Value: *ins.OCRDevelopmentMode, Msg: "insecure configs are not allowed on secure builds"}) } if ins.InfiniteDepthQueries != nil && *ins.InfiniteDepthQueries { - err = multierr.Append(err, configutils.ErrInvalid{Name: "InfiniteDepthQueries", Value: *ins.InfiniteDepthQueries, Msg: "insecure configs are not allowed on secure builds"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "InfiniteDepthQueries", Value: *ins.InfiniteDepthQueries, Msg: "insecure configs are not allowed on secure builds"}) } if ins.DisableRateLimiting != nil && *ins.DisableRateLimiting { - err = multierr.Append(err, configutils.ErrInvalid{Name: "DisableRateLimiting", Value: *ins.DisableRateLimiting, Msg: "insecure configs are not allowed on secure builds"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "DisableRateLimiting", Value: *ins.DisableRateLimiting, Msg: "insecure configs are not allowed on secure builds"}) } return err } @@ -1318,7 +1317,7 @@ func (m *MercuryTLS) setFrom(f *MercuryTLS) { func (m *MercuryTLS) ValidateConfig() (err error) { if *m.CertFile != "" { if !isValidFilePath(*m.CertFile) { - err = multierr.Append(err, configutils.ErrInvalid{Name: "CertFile", Value: *m.CertFile, Msg: "must be a valid file path"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "CertFile", Value: *m.CertFile, Msg: "must be a valid file path"}) } } return @@ -1374,7 +1373,7 @@ func (m *MercurySecrets) validateMerge(f *MercurySecrets) (err error) { if m.Credentials != nil && f.Credentials != nil { for k := range f.Credentials { if _, exists := m.Credentials[k]; exists { - err = multierr.Append(err, configutils.ErrOverride{Name: fmt.Sprintf("Credentials[\"%s\"]", k)}) + err = errors.Join(err, configutils.ErrOverride{Name: fmt.Sprintf("Credentials[\"%s\"]", k)}) } } } @@ -1386,19 +1385,19 @@ func (m *MercurySecrets) ValidateConfig() (err error) { urls := make(map[string]struct{}, len(m.Credentials)) for name, creds := range m.Credentials { if name == "" { - err = multierr.Append(err, configutils.ErrEmpty{Name: "Name", Msg: "must be provided and non-empty"}) + err = errors.Join(err, configutils.ErrEmpty{Name: "Name", Msg: "must be provided and non-empty"}) } if creds.URL == nil || creds.URL.URL() == nil { - err = multierr.Append(err, configutils.ErrMissing{Name: "URL", Msg: "must be provided and non-empty"}) + err = errors.Join(err, configutils.ErrMissing{Name: "URL", Msg: "must be provided and non-empty"}) continue } if creds.LegacyURL != nil && creds.LegacyURL.URL() == nil { - err = multierr.Append(err, configutils.ErrMissing{Name: "Legacy URL", Msg: "must be a valid URL"}) + err = errors.Join(err, configutils.ErrMissing{Name: "Legacy URL", Msg: "must be a valid URL"}) continue } s := creds.URL.URL().String() if _, exists := urls[s]; exists { - err = multierr.Append(err, configutils.NewErrDuplicate("URL", s)) + err = errors.Join(err, configutils.NewErrDuplicate("URL", s)) } urls[s] = struct{}{} } @@ -1424,7 +1423,7 @@ func (t *ThresholdKeyShareSecrets) SetFrom(f *ThresholdKeyShareSecrets) (err err func (t *ThresholdKeyShareSecrets) validateMerge(f *ThresholdKeyShareSecrets) (err error) { if t.ThresholdKeyShare != nil && f.ThresholdKeyShare != nil { - err = multierr.Append(err, configutils.ErrOverride{Name: "ThresholdKeyShare"}) + err = errors.Join(err, configutils.ErrOverride{Name: "ThresholdKeyShare"}) } return err @@ -1471,7 +1470,7 @@ func (t *Tracing) ValidateConfig() (err error) { if t.SamplingRatio != nil { if *t.SamplingRatio < 0 || *t.SamplingRatio > 1 { - err = multierr.Append(err, configutils.ErrInvalid{Name: "SamplingRatio", Value: *t.SamplingRatio, Msg: "must be between 0 and 1"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "SamplingRatio", Value: *t.SamplingRatio, Msg: "must be between 0 and 1"}) } } @@ -1480,18 +1479,18 @@ func (t *Tracing) ValidateConfig() (err error) { case "tls": // TLSCertPath must be set if t.TLSCertPath == nil { - err = multierr.Append(err, configutils.ErrMissing{Name: "TLSCertPath", Msg: "must be set when Tracing.Mode is tls"}) + err = errors.Join(err, configutils.ErrMissing{Name: "TLSCertPath", Msg: "must be set when Tracing.Mode is tls"}) } else { ok := isValidFilePath(*t.TLSCertPath) if !ok { - err = multierr.Append(err, configutils.ErrInvalid{Name: "TLSCertPath", Value: *t.TLSCertPath, Msg: "must be a valid file path"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "TLSCertPath", Value: *t.TLSCertPath, Msg: "must be a valid file path"}) } } case "unencrypted": // no-op default: // Mode must be either "tls" or "unencrypted" - err = multierr.Append(err, configutils.ErrInvalid{Name: "Mode", Value: *t.Mode, Msg: "must be either 'tls' or 'unencrypted'"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "Mode", Value: *t.Mode, Msg: "must be either 'tls' or 'unencrypted'"}) } } @@ -1499,12 +1498,12 @@ func (t *Tracing) ValidateConfig() (err error) { switch *t.Mode { case "tls": if !isValidURI(*t.CollectorTarget) { - err = multierr.Append(err, configutils.ErrInvalid{Name: "CollectorTarget", Value: *t.CollectorTarget, Msg: "must be a valid URI"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "CollectorTarget", Value: *t.CollectorTarget, Msg: "must be a valid URI"}) } case "unencrypted": // Unencrypted traces can not be sent to external networks if !isValidLocalURI(*t.CollectorTarget) { - err = multierr.Append(err, configutils.ErrInvalid{Name: "CollectorTarget", Value: *t.CollectorTarget, Msg: "must be a valid local URI"}) + err = errors.Join(err, configutils.ErrInvalid{Name: "CollectorTarget", Value: *t.CollectorTarget, Msg: "must be a valid local URI"}) } default: // no-op diff --git a/core/gethwrappers/versions.go b/core/gethwrappers/versions.go index acdefd06a59..34f5b4ea49d 100644 --- a/core/gethwrappers/versions.go +++ b/core/gethwrappers/versions.go @@ -2,6 +2,7 @@ package gethwrappers import ( "bufio" + "errors" "fmt" "os" "path/filepath" @@ -9,8 +10,7 @@ import ( "sort" "strings" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" ) // ContractVersion records information about the solidity compiler artifact a @@ -44,11 +44,11 @@ func dbPath() (path string, err error) { func versionsDBLineReader() (*bufio.Scanner, error) { versionsDBPath, err := dbPath() if err != nil { - return nil, errors.Wrapf(err, "could not construct versions DB path") + return nil, pkgerrors.Wrapf(err, "could not construct versions DB path") } versionsDBFile, err := os.Open(versionsDBPath) if err != nil { - return nil, errors.Wrapf(err, "could not open versions database") + return nil, pkgerrors.Wrapf(err, "could not open versions database") } return bufio.NewScanner(versionsDBFile), nil @@ -66,28 +66,28 @@ func ReadVersionsDB() (*IntegratedVersion, error) { for db.Scan() { line := strings.Fields(db.Text()) if !strings.HasSuffix(line[0], ":") { - return nil, errors.Errorf( + return nil, pkgerrors.Errorf( `each line in versions.txt should start with "$TOPIC:"`) } topic := stripTrailingColon(line[0], "") if topic == "GETH_VERSION" { if len(line) != 2 { - return nil, errors.Errorf("GETH_VERSION line should contain geth "+ + return nil, pkgerrors.Errorf("GETH_VERSION line should contain geth "+ "version, and only that: %s", line) } if rv.GethVersion != "" { - return nil, errors.Errorf("more than one geth version") + return nil, pkgerrors.Errorf("more than one geth version") } rv.GethVersion = line[1] } else { // It's a wrapper from a compiler artifact if len(line) != 4 { - return nil, errors.Errorf(`"%s" should have four elements `+ + return nil, pkgerrors.Errorf(`"%s" should have four elements `+ `": "`, db.Text()) } _, alreadyExists := rv.ContractVersions[topic] if alreadyExists { - return nil, errors.Errorf(`topic "%s" already mentioned`, topic) + return nil, pkgerrors.Errorf(`topic "%s" already mentioned`, topic) } rv.ContractVersions[topic] = ContractVersion{ AbiPath: line[1], BinaryPath: line[2], Hash: line[3], @@ -102,24 +102,24 @@ var stripTrailingColon = regexp.MustCompile(":$").ReplaceAllString func WriteVersionsDB(db *IntegratedVersion) (err error) { versionsDBPath, err := dbPath() if err != nil { - return errors.Wrap(err, "could not construct path to versions DB") + return pkgerrors.Wrap(err, "could not construct path to versions DB") } f, err := os.Create(versionsDBPath) if err != nil { - return errors.Wrapf(err, "while opening %s", versionsDBPath) + return pkgerrors.Wrapf(err, "while opening %s", versionsDBPath) } defer func() { if cerr := f.Close(); cerr != nil { - err = multierr.Append(err, cerr) + err = errors.Join(err, cerr) } }() gethLine := "GETH_VERSION: " + db.GethVersion + "\n" n, err := f.WriteString(gethLine) if err != nil { - return errors.Wrapf(err, "while recording geth version line") + return pkgerrors.Wrapf(err, "while recording geth version line") } if n != len(gethLine) { - return errors.Errorf("failed to write entire geth version line, %s", gethLine) + return pkgerrors.Errorf("failed to write entire geth version line, %s", gethLine) } var pkgNames []string for name := range db.ContractVersions { @@ -132,10 +132,10 @@ func WriteVersionsDB(db *IntegratedVersion) (err error) { vinfo.AbiPath, vinfo.BinaryPath, vinfo.Hash) n, err = f.WriteString(versionLine) if err != nil { - return errors.Wrapf(err, "while recording %s version line", name) + return pkgerrors.Wrapf(err, "while recording %s version line", name) } if n != len(versionLine) { - return errors.Errorf("failed to write entire version line %s", versionLine) + return pkgerrors.Errorf("failed to write entire version line %s", versionLine) } } return nil diff --git a/core/services/blockhashstore/feeder.go b/core/services/blockhashstore/feeder.go index 8cc607db9b3..2c139056f8b 100644 --- a/core/services/blockhashstore/feeder.go +++ b/core/services/blockhashstore/feeder.go @@ -2,13 +2,13 @@ package blockhashstore import ( "context" + "errors" "fmt" "sync" "time" "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" "golang.org/x/exp/maps" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -111,7 +111,7 @@ func (f *Feeder) Run(ctx context.Context) error { latestBlock, err := f.latestBlock(ctx) if err != nil { f.lggr.Errorw("Failed to fetch current block number", "err", err) - return errors.Wrap(err, "fetching block number") + return pkgerrors.Wrap(err, "fetching block number") } fromBlock, toBlock := GetSearchWindow(int(latestBlock), f.waitBlocks, f.lookbackBlocks) @@ -145,7 +145,7 @@ func (f *Feeder) Run(ctx context.Context) error { f.lggr.Errorw("Failed to check if block is already stored, attempting to store anyway", "err", err, "block", block) - errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) + errs = errors.Join(errs, pkgerrors.Wrap(err, "checking if stored")) } else if stored { // IsStored() can be based on unfinalized blocks. Therefore, f.stored mapping is not updated f.lggr.Infow("Blockhash already stored", @@ -158,7 +158,7 @@ func (f *Feeder) Run(ctx context.Context) error { err = f.bhs.Store(ctx, block) if err != nil { f.lggr.Errorw("Failed to store block", "err", err, "block", block) - errs = multierr.Append(errs, errors.Wrap(err, "storing block")) + errs = errors.Join(errs, pkgerrors.Wrap(err, "storing block")) continue } @@ -216,7 +216,7 @@ func (f *Feeder) runTrusted( "err", err, "block", block) f.errsLock.Lock() - errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) + errs = errors.Join(errs, pkgerrors.Wrap(err, "checking if stored")) f.errsLock.Unlock() } else if stored { f.lggr.Infow("Blockhash already stored", @@ -250,7 +250,7 @@ func (f *Feeder) runTrusted( f.lggr.Errorw("Failed to get blocks range", "err", err, "blocks", batch) - errs = multierr.Append(errs, errors.Wrap(err, "log poller get blocks range")) + errs = errors.Join(errs, pkgerrors.Wrap(err, "log poller get blocks range")) return errs } @@ -285,7 +285,7 @@ func (f *Feeder) runTrusted( "latestBlock", latestBlock, "latestBlockhash", latestBlockhash, ) - errs = multierr.Append(errs, errors.Wrap(err, "checking if stored")) + errs = errors.Join(errs, pkgerrors.Wrap(err, "checking if stored")) return errs } for i, block := range blocksToStore { diff --git a/core/services/blockheaderfeeder/delegate.go b/core/services/blockheaderfeeder/delegate.go index 53f514cee27..9241e485a7d 100644 --- a/core/services/blockheaderfeeder/delegate.go +++ b/core/services/blockheaderfeeder/delegate.go @@ -2,11 +2,11 @@ package blockheaderfeeder import ( "context" + "errors" "fmt" "time" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -51,7 +51,7 @@ func (d *Delegate) JobType() job.Type { // ServicesForSpec satisfies the job.Delegate interface. func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if jb.BlockHeaderFeederSpec == nil { - return nil, errors.Errorf("Delegate expects a BlockHeaderFeederSpec to be present, got %+v", jb) + return nil, pkgerrors.Errorf("Delegate expects a BlockHeaderFeederSpec to be present, got %+v", jb) } chain, err := d.legacyChains.Get(jb.BlockHeaderFeederSpec.EVMChainID.String()) @@ -61,7 +61,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } if !chain.Config().Feature().LogPoller() { - return nil, errors.New("log poller must be enabled to run blockheaderfeeder") + return nil, pkgerrors.New("log poller must be enabled to run blockheaderfeeder") } if jb.BlockHeaderFeederSpec.LookbackBlocks < int32(chain.Config().EVM().FinalityDepth()) { @@ -72,7 +72,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { keys, err := d.ks.EnabledKeysForChain(chain.ID()) if err != nil { - return nil, errors.Wrap(err, "getting sending keys") + return nil, pkgerrors.Wrap(err, "getting sending keys") } if len(keys) == 0 { return nil, fmt.Errorf("missing sending keys for chain ID: %v", chain.ID()) @@ -85,13 +85,13 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { bhs, err := blockhash_store.NewBlockhashStore( jb.BlockHeaderFeederSpec.BlockhashStoreAddress.Address(), chain.Client()) if err != nil { - return nil, errors.Wrap(err, "building BHS") + return nil, pkgerrors.Wrap(err, "building BHS") } batchBlockhashStore, err := batch_blockhash_store.NewBatchBlockhashStore( jb.BlockHeaderFeederSpec.BatchBlockhashStoreAddress.Address(), chain.Client()) if err != nil { - return nil, errors.Wrap(err, "building batch BHS") + return nil, pkgerrors.Wrap(err, "building batch BHS") } lp := chain.LogPoller() @@ -101,12 +101,12 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if c, err = v1.NewVRFCoordinator( jb.BlockHeaderFeederSpec.CoordinatorV1Address.Address(), chain.Client()); err != nil { - return nil, errors.Wrap(err, "building V1 coordinator") + return nil, pkgerrors.Wrap(err, "building V1 coordinator") } var coord *blockhashstore.V1Coordinator coord, err = blockhashstore.NewV1Coordinator(c, lp) if err != nil { - return nil, errors.Wrap(err, "building V1 coordinator") + return nil, pkgerrors.Wrap(err, "building V1 coordinator") } coordinators = append(coordinators, coord) } @@ -115,12 +115,12 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if c, err = v2.NewVRFCoordinatorV2( jb.BlockHeaderFeederSpec.CoordinatorV2Address.Address(), chain.Client()); err != nil { - return nil, errors.Wrap(err, "building V2 coordinator") + return nil, pkgerrors.Wrap(err, "building V2 coordinator") } var coord *blockhashstore.V2Coordinator coord, err = blockhashstore.NewV2Coordinator(c, lp) if err != nil { - return nil, errors.Wrap(err, "building V2 coordinator") + return nil, pkgerrors.Wrap(err, "building V2 coordinator") } coordinators = append(coordinators, coord) } @@ -129,19 +129,19 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if c, err = v2plus.NewIVRFCoordinatorV2PlusInternal( jb.BlockHeaderFeederSpec.CoordinatorV2PlusAddress.Address(), chain.Client()); err != nil { - return nil, errors.Wrap(err, "building V2 plus coordinator") + return nil, pkgerrors.Wrap(err, "building V2 plus coordinator") } var coord *blockhashstore.V2PlusCoordinator coord, err = blockhashstore.NewV2PlusCoordinator(c, lp) if err != nil { - return nil, errors.Wrap(err, "building V2 plus coordinator") + return nil, pkgerrors.Wrap(err, "building V2 plus coordinator") } coordinators = append(coordinators, coord) } bpBHS, err := blockhashstore.NewBulletproofBHS(chain.Config().EVM().GasEstimator(), chain.Config().Database(), fromAddresses, chain.TxManager(), bhs, nil, chain.ID(), d.ks) if err != nil { - return nil, errors.Wrap(err, "building bulletproof bhs") + return nil, pkgerrors.Wrap(err, "building bulletproof bhs") } batchBHS, err := blockhashstore.NewBatchBHS( @@ -154,7 +154,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { d.logger, ) if err != nil { - return nil, errors.Wrap(err, "building batchBHS") + return nil, pkgerrors.Wrap(err, "building batchBHS") } log := d.logger.Named("BlockHeaderFeeder").With( @@ -177,7 +177,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { func(ctx context.Context) (uint64, error) { head, err := chain.Client().HeadByNumber(ctx, nil) if err != nil { - return 0, errors.Wrap(err, "getting chain head") + return 0, pkgerrors.Wrap(err, "getting chain head") } return uint64(head.Number), nil }, @@ -272,7 +272,7 @@ func (s *service) runFeeder() { func CheckFromAddressesExist(jb job.Job, gethks keystore.Eth) (err error) { for _, a := range jb.BlockHeaderFeederSpec.FromAddresses { _, err2 := gethks.Get(a.Hex()) - err = multierr.Append(err, err2) + err = errors.Join(err, err2) } return } diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 7b4a9951460..ecb26e13f1c 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -14,7 +14,6 @@ import ( "github.com/google/uuid" "github.com/grafana/pyroscope-go" pkgerrors "github.com/pkg/errors" - "go.uber.org/multierr" "go.uber.org/zap/zapcore" "github.com/jmoiron/sqlx" @@ -595,7 +594,7 @@ func (app *ChainlinkApplication) stop() (err error) { return } if lerr := app.closeLogger(); lerr != nil { - err = multierr.Append(err, lerr) + err = errors.Join(err, lerr) } }() app.logger.Info("Gracefully exiting...") @@ -604,24 +603,24 @@ func (app *ChainlinkApplication) stop() (err error) { for i := len(app.srvcs) - 1; i >= 0; i-- { service := app.srvcs[i] app.logger.Debugw("Closing service...", "name", service.Name()) - err = multierr.Append(err, service.Close()) + err = errors.Join(err, service.Close()) } app.logger.Debug("Stopping SessionReaper...") - err = multierr.Append(err, app.SessionReaper.Stop()) + err = errors.Join(err, app.SessionReaper.Stop()) app.logger.Debug("Closing HealthChecker...") - err = multierr.Append(err, app.HealthChecker.Close()) + err = errors.Join(err, app.HealthChecker.Close()) if app.FeedsService != nil { app.logger.Debug("Closing Feeds Service...") - err = multierr.Append(err, app.FeedsService.Close()) + err = errors.Join(err, app.FeedsService.Close()) } if app.Nurse != nil { - err = multierr.Append(err, app.Nurse.Close()) + err = errors.Join(err, app.Nurse.Close()) } if app.profiler != nil { - err = multierr.Append(err, app.profiler.Stop()) + err = errors.Join(err, app.profiler.Stop()) } app.logger.Info("Exited all services") diff --git a/core/services/chainlink/config.go b/core/services/chainlink/config.go index 6cd2732ece8..dcbce6cb00c 100644 --- a/core/services/chainlink/config.go +++ b/core/services/chainlink/config.go @@ -4,8 +4,6 @@ import ( "errors" "fmt" - "go.uber.org/multierr" - gotoml "github.com/pelletier/go-toml/v2" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" @@ -56,7 +54,7 @@ func (c *Config) TOMLString() (string, error) { func (c *Config) warnings() (err error) { deprecationErr := c.deprecationWarnings() warningErr := c.valueWarnings() - err = multierr.Append(deprecationErr, warningErr) + err = errors.Join(deprecationErr, warningErr) _, list := utils.MultiErrorList(err) return list } @@ -66,7 +64,7 @@ func (c *Config) valueWarnings() (err error) { if c.Tracing.Enabled != nil && *c.Tracing.Enabled { if c.Tracing.Mode != nil && *c.Tracing.Mode == "unencrypted" { if c.Tracing.TLSCertPath != nil { - err = multierr.Append(err, config.ErrInvalid{Name: "Tracing.TLSCertPath", Value: *c.Tracing.TLSCertPath, Msg: "must be empty when Tracing.Mode is 'unencrypted'"}) + err = errors.Join(err, config.ErrInvalid{Name: "Tracing.TLSCertPath", Value: *c.Tracing.TLSCertPath, Msg: "must be empty when Tracing.Mode is 'unencrypted'"}) } } } @@ -129,19 +127,19 @@ func (c *Config) SetFrom(f *Config) (err error) { c.Core.SetFrom(&f.Core) if err1 := c.EVM.SetFrom(&f.EVM); err1 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err1, "EVM")) + err = errors.Join(err, config.NamedMultiErrorList(err1, "EVM")) } if err2 := c.Cosmos.SetFrom(&f.Cosmos); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Cosmos")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Cosmos")) } if err3 := c.Solana.SetFrom(&f.Solana); err3 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err3, "Solana")) + err = errors.Join(err, config.NamedMultiErrorList(err3, "Solana")) } if err4 := c.Starknet.SetFrom(&f.Starknet); err4 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err4, "Starknet")) + err = errors.Join(err, config.NamedMultiErrorList(err4, "Starknet")) } _, err = utils.MultiErrorList(err) @@ -155,31 +153,31 @@ type Secrets struct { func (s *Secrets) SetFrom(f *Secrets) (err error) { if err2 := s.Database.SetFrom(&f.Database); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Database")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Database")) } if err2 := s.Password.SetFrom(&f.Password); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Password")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Password")) } if err2 := s.WebServer.SetFrom(&f.WebServer); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "WebServer")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "WebServer")) } if err2 := s.Pyroscope.SetFrom(&f.Pyroscope); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Pyroscope")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Pyroscope")) } if err2 := s.Prometheus.SetFrom(&f.Prometheus); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Prometheus")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Prometheus")) } if err2 := s.Mercury.SetFrom(&f.Mercury); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Mercury")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Mercury")) } if err2 := s.Threshold.SetFrom(&f.Threshold); err2 != nil { - err = multierr.Append(err, config.NamedMultiErrorList(err2, "Threshold")) + err = errors.Join(err, config.NamedMultiErrorList(err2, "Threshold")) } _, err = utils.MultiErrorList(err) diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go index ce3ba3a3099..576c62a7927 100644 --- a/core/services/chainlink/config_general.go +++ b/core/services/chainlink/config_general.go @@ -11,7 +11,6 @@ import ( "time" pkgerrors "github.com/pkg/errors" - "go.uber.org/multierr" "go.uber.org/zap/zapcore" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" @@ -251,7 +250,7 @@ func validateEnv() (err error) { k := kv[:i] _, ok := os.LookupEnv(k) if ok { - err = multierr.Append(err, fmt.Errorf("environment variable %s must not be set: %v", k, v2.ErrUnsupported)) + err = errors.Join(err, fmt.Errorf("environment variable %s must not be set: %v", k, v2.ErrUnsupported)) } } return diff --git a/core/services/gateway/connectionmanager.go b/core/services/gateway/connectionmanager.go index 52734f9927f..49219c2108e 100644 --- a/core/services/gateway/connectionmanager.go +++ b/core/services/gateway/connectionmanager.go @@ -13,7 +13,6 @@ import ( "github.com/gorilla/websocket" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -175,7 +174,7 @@ func (m *connectionManager) StartHandshake(authHeader []byte) (attemptId string, m.lggr.Debug("StartHandshake") authHeaderElems, signer, err := network.UnpackSignedAuthHeader(authHeader) if err != nil { - return "", nil, multierr.Append(network.ErrAuthHeaderParse, err) + return "", nil, errors.Join(network.ErrAuthHeaderParse, err) } nodeAddress := "0x" + hex.EncodeToString(signer) donConnMgr, ok := m.dons[authHeaderElems.DonId] diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go index a6a2f40f855..31cd5b1807a 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20/registry.go @@ -2,6 +2,7 @@ package evm import ( "context" + "errors" "fmt" "math/big" "strings" @@ -15,7 +16,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" - "go.uber.org/multierr" ocr2keepers "github.com/smartcontractkit/chainlink-automation/pkg/v2" @@ -618,7 +618,7 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, keys []ocr2keepers.Upkee for i, req := range checkReqs { if req.Error != nil { r.lggr.Debugf("error encountered for key %s with message '%s' in check", keys[i], req.Error) - multierr.AppendInto(&multiErr, req.Error) + multiErr = errors.Join(multiErr, req.Error) } else { var err error r.lggr.Debugf("UnpackCheckResult key %s checkResult: %s", string(keys[i]), *checkResults[i]) @@ -684,7 +684,7 @@ func (r *EvmRegistry) simulatePerformUpkeeps(ctx context.Context, checkResults [ for i, req := range performReqs { if req.Error != nil { r.lggr.Debugf("error encountered for key %d|%s with message '%s' in simulate perform", checkResults[i].Block, checkResults[i].ID, req.Error) - multierr.AppendInto(&multiErr, req.Error) + multiErr = errors.Join(multiErr, req.Error) } else { simulatePerformSuccess, err := r.packer.UnpackPerformResult(*performResults[i]) if err != nil { @@ -750,7 +750,7 @@ func (r *EvmRegistry) getUpkeepConfigs(ctx context.Context, ids []*big.Int) ([]a for i, req := range uReqs { if req.Error != nil { r.lggr.Debugf("error encountered for config id %s with message '%s' in get config", ids[i], req.Error) - multierr.AppendInto(&multiErr, req.Error) + multiErr = errors.Join(multiErr, req.Error) } else { var err error results[i], err = r.packer.UnpackUpkeepResult(ids[i], *uResults[i]) diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go index fd7bfa91d7f..0ae3007bcf0 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/registry.go @@ -2,7 +2,7 @@ package evm import ( "context" - goerrors "errors" + "errors" "fmt" "math/big" "net/http" @@ -18,8 +18,7 @@ import ( "github.com/ethereum/go-ethereum/common" coreTypes "github.com/ethereum/go-ethereum/core/types" "github.com/patrickmn/go-cache" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -324,7 +323,7 @@ func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error { idBatch := ids[i:end] if batchErr := r.refreshLogTriggerUpkeepsBatch(idBatch); batchErr != nil { - multierr.AppendInto(&err, batchErr) + err = errors.Join(err, batchErr) } time.Sleep(500 * time.Millisecond) @@ -394,7 +393,7 @@ func (r *EvmRegistry) refreshLogTriggerUpkeepsBatch(logTriggerIDs []*big.Int) er logBlock = unpausedBlockNumbers[id.String()] } if err := r.updateTriggerConfig(id, config, logBlock); err != nil { - merr = goerrors.Join(merr, fmt.Errorf("failed to update trigger config for upkeep id %s: %w", id.String(), err)) + merr = errors.Join(merr, fmt.Errorf("failed to update trigger config for upkeep id %s: %w", id.String(), err)) } } @@ -592,7 +591,7 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint if len(cfg) == 0 { fetched, err := r.fetchTriggerConfig(id) if err != nil { - return errors.Wrap(err, "failed to fetch log upkeep config") + return pkgerrors.Wrap(err, "failed to fetch log upkeep config") } cfg = fetched } @@ -607,7 +606,7 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint UpkeepID: id, UpdateBlock: logBlock, }); err != nil { - return errors.Wrap(err, "failed to register log filter") + return pkgerrors.Wrap(err, "failed to register log filter") } r.lggr.Debugw("registered log filter", "upkeepID", id.String(), "cfg", parsed) default: diff --git a/core/services/ocrcommon/validate.go b/core/services/ocrcommon/validate.go index f7ebcf79466..dde5b137dae 100644 --- a/core/services/ocrcommon/validate.go +++ b/core/services/ocrcommon/validate.go @@ -1,9 +1,10 @@ package ocrcommon import ( + "errors" + "github.com/pelletier/go-toml" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" ) // CloneSet returns a copy of the input map. @@ -22,12 +23,12 @@ func ValidateExplicitlySetKeys(tree *toml.Tree, expected map[string]struct{}, no // top level keys only for _, k := range tree.Keys() { if _, ok := notExpected[k]; ok { - err = multierr.Append(err, errors.Errorf("unrecognised key for %s peer: %s", peerType, k)) + err = errors.Join(err, pkgerrors.Errorf("unrecognised key for %s peer: %s", peerType, k)) } delete(expected, k) } for missing := range expected { - err = multierr.Append(err, errors.Errorf("missing required key %s", missing)) + err = errors.Join(err, pkgerrors.Errorf("missing required key %s", missing)) } return err } diff --git a/core/services/telemetry/manager.go b/core/services/telemetry/manager.go index c457aca5bf8..5c76cfb349b 100644 --- a/core/services/telemetry/manager.go +++ b/core/services/telemetry/manager.go @@ -2,12 +2,12 @@ package telemetry import ( "context" + "errors" "net/url" "strings" "time" - "github.com/pkg/errors" - "go.uber.org/multierr" + pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/libocr/commontypes" @@ -118,7 +118,7 @@ func (m *Manager) Start(ctx context.Context) error { return m.StartOnce("TelemetryManager", func() error { var err error for _, e := range m.endpoints { - err = multierr.Append(err, e.client.Start(ctx)) + err = errors.Join(err, e.client.Start(ctx)) } return err }) @@ -127,7 +127,7 @@ func (m *Manager) Close() error { return m.StopOnce("TelemetryManager", func() error { var err error for _, e := range m.endpoints { - err = multierr.Append(err, e.client.Close()) + err = errors.Join(err, e.client.Close()) } return err }) @@ -166,23 +166,23 @@ func (m *Manager) GenMonitoringEndpoint(network string, chainID string, contract func (m *Manager) addEndpoint(e config.TelemetryIngressEndpoint) error { if e.Network() == "" && !m.legacyMode { - return errors.New("cannot add telemetry endpoint, network cannot be empty") + return pkgerrors.New("cannot add telemetry endpoint, network cannot be empty") } if e.ChainID() == "" && !m.legacyMode { - return errors.New("cannot add telemetry endpoint, chainID cannot be empty") + return pkgerrors.New("cannot add telemetry endpoint, chainID cannot be empty") } if e.URL() == nil { - return errors.New("cannot add telemetry endpoint, URL cannot be empty") + return pkgerrors.New("cannot add telemetry endpoint, URL cannot be empty") } if e.ServerPubKey() == "" { - return errors.New("cannot add telemetry endpoint, ServerPubKey cannot be empty") + return pkgerrors.New("cannot add telemetry endpoint, ServerPubKey cannot be empty") } if _, found := m.getEndpoint(e.Network(), e.ChainID()); found { - return errors.Errorf("cannot add telemetry endpoint for network %q and chainID %q, endpoint already exists", e.Network(), e.ChainID()) + return pkgerrors.Errorf("cannot add telemetry endpoint for network %q and chainID %q, endpoint already exists", e.Network(), e.ChainID()) } var tClient synchronization.TelemetryService diff --git a/core/services/vrf/delegate.go b/core/services/vrf/delegate.go index ecabbc09c71..971982c1031 100644 --- a/core/services/vrf/delegate.go +++ b/core/services/vrf/delegate.go @@ -1,14 +1,14 @@ package vrf import ( + "errors" "fmt" "time" "github.com/avast/retry-go/v4" "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/theodesp/go-heaps/pairing" - "go.uber.org/multierr" "github.com/jmoiron/sqlx" @@ -74,7 +74,7 @@ func (d *Delegate) OnDeleteJob(job.Job, pg.Queryer) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if jb.VRFSpec == nil || jb.PipelineSpec == nil { - return nil, errors.Errorf("vrf.Delegate expects a VRFSpec and PipelineSpec to be present, got %+v", jb) + return nil, pkgerrors.Errorf("vrf.Delegate expects a VRFSpec and PipelineSpec to be present, got %+v", jb) } pl, err := jb.PipelineSpec.ParsePipeline() if err != nil { @@ -103,7 +103,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { batchCoordinatorV2, err = batch_vrf_coordinator_v2.NewBatchVRFCoordinatorV2( jb.VRFSpec.BatchCoordinatorAddress.Address(), chain.Client()) if err != nil { - return nil, errors.Wrap(err, "create batch coordinator wrapper") + return nil, pkgerrors.Wrap(err, "create batch coordinator wrapper") } } @@ -113,7 +113,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { jb.VRFSpec.VRFOwnerAddress.Address(), chain.Client(), ) if err != nil { - return nil, errors.Wrap(err, "create vrf owner wrapper") + return nil, pkgerrors.Wrap(err, "create vrf owner wrapper") } } @@ -133,17 +133,17 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } if !FromAddressMaxGasPricesAllEqual(jb, chain.Config().EVM().GasEstimator().PriceMaxKey) { - return nil, errors.New("key-specific max gas prices of all fromAddresses are not equal, please set them to equal values") + return nil, pkgerrors.New("key-specific max gas prices of all fromAddresses are not equal, please set them to equal values") } if err2 := CheckFromAddressMaxGasPrices(jb, chain.Config().EVM().GasEstimator().PriceMaxKey); err != nil { return nil, err2 } if vrfOwner != nil { - return nil, errors.New("VRF Owner is not supported for VRF V2 Plus") + return nil, pkgerrors.New("VRF Owner is not supported for VRF V2 Plus") } if jb.VRFSpec.CustomRevertsPipelineEnabled { - return nil, errors.New("Custom Reverted Txns Pipeline is not supported for VRF V2 Plus") + return nil, pkgerrors.New("Custom Reverted Txns Pipeline is not supported for VRF V2 Plus") } // Get the LINKNATIVEFEED address with retries @@ -155,12 +155,12 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return err }, retry.Attempts(10), retry.Delay(500*time.Millisecond)) if err != nil { - return nil, errors.Wrap(err, "can't call LINKNATIVEFEED") + return nil, pkgerrors.Wrap(err, "can't call LINKNATIVEFEED") } aggregator, err2 := aggregator_v3_interface.NewAggregatorV3Interface(linkNativeFeedAddress, chain.Client()) if err2 != nil { - return nil, errors.Wrap(err2, "NewAggregatorV3Interface") + return nil, pkgerrors.Wrap(err2, "NewAggregatorV3Interface") } return []job.ServiceCtx{ @@ -192,7 +192,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } if !FromAddressMaxGasPricesAllEqual(jb, chain.Config().EVM().GasEstimator().PriceMaxKey) { - return nil, errors.New("key-specific max gas prices of all fromAddresses are not equal, please set them to equal values") + return nil, pkgerrors.New("key-specific max gas prices of all fromAddresses are not equal, please set them to equal values") } if err2 := CheckFromAddressMaxGasPrices(jb, chain.Config().EVM().GasEstimator().PriceMaxKey); err != nil { @@ -208,11 +208,11 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return err }, retry.Attempts(10), retry.Delay(500*time.Millisecond)) if err != nil { - return nil, errors.Wrap(err, "LINKETHFEED") + return nil, pkgerrors.Wrap(err, "LINKETHFEED") } aggregator, err := aggregator_v3_interface.NewAggregatorV3Interface(linkEthFeedAddress, chain.Client()) if err != nil { - return nil, errors.Wrap(err, "NewAggregatorV3Interface") + return nil, pkgerrors.Wrap(err, "NewAggregatorV3Interface") } if vrfOwner == nil { lV2.Infow("Running without VRFOwnerAddress set on the spec") @@ -264,7 +264,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { }}, nil } } - return nil, errors.New("invalid job spec expected a vrf task") + return nil, pkgerrors.New("invalid job spec expected a vrf task") } // CheckFromAddressesExist returns an error if and only if one of the addresses @@ -272,7 +272,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { func CheckFromAddressesExist(jb job.Job, gethks keystore.Eth) (err error) { for _, a := range jb.VRFSpec.FromAddresses { _, err2 := gethks.Get(a.Hex()) - err = multierr.Append(err, err2) + err = errors.Join(err, err2) } return } @@ -285,7 +285,7 @@ func CheckFromAddressMaxGasPrices(jb job.Job, keySpecificMaxGas keySpecificMaxGa if jb.VRFSpec.GasLanePrice != nil { for _, a := range jb.VRFSpec.FromAddresses { if keySpecific := keySpecificMaxGas(a.Address()); !keySpecific.Equal(jb.VRFSpec.GasLanePrice) { - err = multierr.Append(err, + err = errors.Join(err, fmt.Errorf( "key-specific max gas price of from address %s (%s) does not match gasLanePriceGWei (%s) specified in job spec", a.Hex(), keySpecific.String(), jb.VRFSpec.GasLanePrice.String())) diff --git a/core/services/vrf/v2/listener_v2_log_listener.go b/core/services/vrf/v2/listener_v2_log_listener.go index 07b4c2c3800..cbb892552e9 100644 --- a/core/services/vrf/v2/listener_v2_log_listener.go +++ b/core/services/vrf/v2/listener_v2_log_listener.go @@ -3,12 +3,12 @@ package v2 import ( "bytes" "context" + "errors" "fmt" "math/big" "time" "github.com/ethereum/go-ethereum/common" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -281,7 +281,7 @@ func (lsn *listenerV2) getUnfulfilled(logs []logpoller.Log, ll logger.Logger) (u parsed, err2 := lsn.coordinator.ParseRandomWordsFulfilled(l.ToGethLog()) if err2 != nil { // should never happen - errs = multierr.Append(errs, err2) + errs = errors.Join(errs, err2) continue } fulfilled[parsed.RequestID().String()] = parsed @@ -289,7 +289,7 @@ func (lsn *listenerV2) getUnfulfilled(logs []logpoller.Log, ll logger.Logger) (u parsed, err2 := lsn.coordinator.ParseRandomWordsRequested(l.ToGethLog()) if err2 != nil { // should never happen - errs = multierr.Append(errs, err2) + errs = errors.Join(errs, err2) continue } keyHash := parsed.KeyHash() diff --git a/core/services/vrf/v2/listener_v2_log_processor.go b/core/services/vrf/v2/listener_v2_log_processor.go index 221900f0029..cd2abe3d350 100644 --- a/core/services/vrf/v2/listener_v2_log_processor.go +++ b/core/services/vrf/v2/listener_v2_log_processor.go @@ -19,7 +19,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" pkgerrors "github.com/pkg/errors" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink-common/pkg/utils/hex" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" @@ -1003,21 +1002,21 @@ func (lsn *listenerV2) checkReqsFulfilled(ctx context.Context, l logger.Logger, var errs error for i, call := range calls { if call.Error != nil { - errs = multierr.Append(errs, fmt.Errorf("checking request %s with hash %s: %w", + errs = errors.Join(errs, fmt.Errorf("checking request %s with hash %s: %w", reqs[i].req.RequestID().String(), reqs[i].req.Raw().TxHash.String(), call.Error)) continue } rString, ok := call.Result.(*string) if !ok { - errs = multierr.Append(errs, + errs = errors.Join(errs, fmt.Errorf("unexpected result %+v on request %s with hash %s", call.Result, reqs[i].req.RequestID().String(), reqs[i].req.Raw().TxHash.String())) continue } result, err := hexutil.Decode(*rString) if err != nil { - errs = multierr.Append(errs, + errs = errors.Join(errs, fmt.Errorf("decoding batch call result %+v %s request %s with hash %s: %w", call.Result, *rString, reqs[i].req.RequestID().String(), reqs[i].req.Raw().TxHash.String(), err)) continue diff --git a/core/store/models/common.go b/core/store/models/common.go index e446481ff64..10d8322b02c 100644 --- a/core/store/models/common.go +++ b/core/store/models/common.go @@ -5,6 +5,7 @@ import ( "database/sql/driver" "encoding/hex" "encoding/json" + "errors" "fmt" "net/url" "regexp" @@ -12,10 +13,9 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/robfig/cron/v3" "github.com/tidwall/gjson" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" @@ -181,7 +181,7 @@ func (c *Cron) UnmarshalJSON(b []byte) error { } if !strings.HasPrefix(s, "CRON_TZ=") { - return errors.New("Cron: specs must specify a time zone using CRON_TZ, e.g. 'CRON_TZ=UTC 5 * * * *'") + return pkgerrors.New("Cron: specs must specify a time zone using CRON_TZ, e.g. 'CRON_TZ=UTC 5 * * * *'") } _, err = CronParser.Parse(s) @@ -233,7 +233,7 @@ func (i *Interval) Scan(v interface{}) error { } asInt64, is := v.(int64) if !is { - return errors.Errorf("models.Interval#Scan() wanted int64, got %T", v) + return pkgerrors.Errorf("models.Interval#Scan() wanted int64, got %T", v) } *i = Interval(time.Duration(asInt64) * time.Nanosecond) return nil @@ -311,7 +311,7 @@ func Merge(inputs ...JSON) (JSON, error) { } case nil: default: - return JSON{}, errors.New("can only merge JSON objects") + return JSON{}, pkgerrors.New("can only merge JSON objects") } } @@ -385,7 +385,7 @@ func (s *Sha256Hash) UnmarshalText(bs []byte) (err error) { func (s *Sha256Hash) Scan(value interface{}) error { bytes, ok := value.([]byte) if !ok { - return errors.Errorf("Failed to unmarshal Sha256Hash value: %v", value) + return pkgerrors.Errorf("Failed to unmarshal Sha256Hash value: %v", value) } if s == nil { *s = Sha256Hash{} @@ -425,7 +425,7 @@ type ServiceHeaders []ServiceHeader func (sh *ServiceHeaders) UnmarshalText(input []byte) error { if sh == nil { - return errors.New("Cannot unmarshal to a nil receiver") + return pkgerrors.New("Cannot unmarshal to a nil receiver") } headers := string(input) @@ -436,7 +436,7 @@ func (sh *ServiceHeaders) UnmarshalText(input []byte) error { for _, header := range headerLines { keyValue := strings.Split(header, "||") if len(keyValue) != 2 { - return errors.Errorf("invalid headers provided for the audit logger. Value, single pair split on || required, got: %s", keyValue) + return pkgerrors.Errorf("invalid headers provided for the audit logger. Value, single pair split on || required, got: %s", keyValue) } h := ServiceHeader{ Header: keyValue[0], @@ -456,7 +456,7 @@ func (sh *ServiceHeaders) UnmarshalText(input []byte) error { func (sh *ServiceHeaders) MarshalText() ([]byte, error) { if sh == nil { - return nil, errors.New("Cannot marshal to a nil receiver") + return nil, pkgerrors.New("Cannot marshal to a nil receiver") } sb := strings.Builder{} @@ -487,11 +487,11 @@ var ( func (h ServiceHeader) Validate() (err error) { if !headerNameRegex.MatchString(h.Header) { - err = multierr.Append(err, errors.Errorf("invalid header name: %s", h.Header)) + err = errors.Join(err, pkgerrors.Errorf("invalid header name: %s", h.Header)) } if !headerValueRegex.MatchString(h.Value) { - err = multierr.Append(err, errors.Errorf("invalid header value: %s", h.Value)) + err = errors.Join(err, pkgerrors.Errorf("invalid header value: %s", h.Value)) } return } diff --git a/core/utils/config/validate.go b/core/utils/config/validate.go index 5fbae24ad53..0699809a92f 100644 --- a/core/utils/config/validate.go +++ b/core/utils/config/validate.go @@ -1,13 +1,13 @@ package config import ( + "errors" "fmt" "reflect" "strconv" "strings" "github.com/Masterminds/semver/v3" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -33,11 +33,11 @@ func validate(v reflect.Value, checkInterface bool) (err error) { if checkInterface { i := v.Interface() if vc, ok := i.(Validated); ok { - err = multierr.Append(err, vc.ValidateConfig()) + err = errors.Join(err, vc.ValidateConfig()) } else if v.CanAddr() { i = v.Addr().Interface() if vc, ok := i.(Validated); ok { - err = multierr.Append(err, vc.ValidateConfig()) + err = errors.Join(err, vc.ValidateConfig()) } } } @@ -72,9 +72,9 @@ func validate(v reflect.Value, checkInterface bool) (err error) { // skip the interface if Anonymous, since the parent struct inherits the methods if fe := validate(fv, !ft.Anonymous); fe != nil { if ft.Anonymous { - err = multierr.Append(err, fe) + err = errors.Join(err, fe) } else { - err = multierr.Append(err, NamedMultiErrorList(fe, ft.Name)) + err = errors.Join(err, NamedMultiErrorList(fe, ft.Name)) } } } @@ -91,7 +91,7 @@ func validate(v reflect.Value, checkInterface bool) (err error) { continue } if me := validate(mv, true); me != nil { - err = multierr.Append(err, NamedMultiErrorList(me, fmt.Sprintf("%s", mk.Interface()))) + err = errors.Join(err, NamedMultiErrorList(me, fmt.Sprintf("%s", mk.Interface()))) } } return @@ -105,7 +105,7 @@ func validate(v reflect.Value, checkInterface bool) (err error) { continue } if me := validate(iv, true); me != nil { - err = multierr.Append(err, NamedMultiErrorList(me, strconv.Itoa(i))) + err = errors.Join(err, NamedMultiErrorList(me, strconv.Itoa(i))) } } return diff --git a/core/web/sessions_controller.go b/core/web/sessions_controller.go index 23ecfd3b798..fb9e6dbf5e0 100644 --- a/core/web/sessions_controller.go +++ b/core/web/sessions_controller.go @@ -7,7 +7,6 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" - "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -60,7 +59,7 @@ func (sc *SessionsController) Create(c *gin.Context) { } if err := saveSessionID(session, sid); err != nil { - jsonAPIError(c, http.StatusInternalServerError, multierr.Append(errors.New("unable to save session id"), err)) + jsonAPIError(c, http.StatusInternalServerError, errors.Join(errors.New("unable to save session id"), err)) return }