multi: Wrap errors for better errors.Is/As support.

This updates all remaining cases of unwrapped errors in fmt.Errorf calls
to wrap the underlying errors with the %w format verb to ensure they
work nicely with errors.Is and errors.As.
This commit is contained in:
Dave Collins 2023-08-25 15:24:16 -05:00
parent ba7e40fa4d
commit 318d81bc90
No known key found for this signature in database
GPG Key ID: B8904D9D9C93D1F2
13 changed files with 64 additions and 68 deletions

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2014 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -531,7 +531,7 @@ func (a *AddrManager) deserializePeers(filePath string) error {
}
r, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("%s error opening file: %v", filePath, err)
return fmt.Errorf("%s error opening file: %w", filePath, err)
}
defer r.Close()
@ -539,7 +539,7 @@ func (a *AddrManager) deserializePeers(filePath string) error {
dec := json.NewDecoder(r)
err = dec.Decode(&sam)
if err != nil {
return fmt.Errorf("error reading %s: %v", filePath, err)
return fmt.Errorf("error reading %s: %w", filePath, err)
}
if sam.Version != serialisationVersion {
@ -551,13 +551,13 @@ func (a *AddrManager) deserializePeers(filePath string) error {
for _, v := range sam.Addresses {
netAddr, err := a.newAddressFromString(v.Addr)
if err != nil {
return fmt.Errorf("failed to deserialize netaddress "+
"%s: %v", v.Addr, err)
return fmt.Errorf("failed to deserialize netaddress %s: %w", v.Addr,
err)
}
srcAddr, err := a.newAddressFromString(v.Src)
if err != nil {
return fmt.Errorf("failed to deserialize netaddress "+
"%s: %v", v.Src, err)
return fmt.Errorf("failed to deserialize netaddress %s: %w", v.Src,
err)
}
ka := &KnownAddress{

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -45,7 +45,7 @@ func NewTLSCertPair(curve elliptic.Curve, organization string, validUntil time.T
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate serial number: %s", err)
return nil, nil, fmt.Errorf("failed to generate serial number: %w", err)
}
host, err := os.Hostname()
@ -120,24 +120,24 @@ func NewTLSCertPair(curve elliptic.Curve, organization string, validUntil time.T
derBytes, err := x509.CreateCertificate(rand.Reader, &template,
&template, &priv.PublicKey, priv)
if err != nil {
return nil, nil, fmt.Errorf("failed to create certificate: %v", err)
return nil, nil, fmt.Errorf("failed to create certificate: %w", err)
}
certBuf := &bytes.Buffer{}
err = pem.Encode(certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if err != nil {
return nil, nil, fmt.Errorf("failed to encode certificate: %v", err)
return nil, nil, fmt.Errorf("failed to encode certificate: %w", err)
}
keybytes, err := x509.MarshalECPrivateKey(priv)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal private key: %v", err)
return nil, nil, fmt.Errorf("failed to marshal private key: %w", err)
}
keyBuf := &bytes.Buffer{}
err = pem.Encode(keyBuf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keybytes})
if err != nil {
return nil, nil, fmt.Errorf("failed to encode private key: %v", err)
return nil, nil, fmt.Errorf("failed to encode private key: %w", err)
}
return certBuf.Bytes(), keyBuf.Bytes(), nil

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2019 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -48,7 +48,7 @@ func NewEd25519TLSCertPair(organization string, validUntil time.Time, extraHosts
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate serial number: %s", err)
return nil, nil, fmt.Errorf("failed to generate serial number: %w", err)
}
host, err := os.Hostname()
@ -123,24 +123,24 @@ func NewEd25519TLSCertPair(organization string, validUntil time.Time, extraHosts
derBytes, err := x509.CreateCertificate(rand.Reader, &template,
&template, priv.Public(), priv)
if err != nil {
return nil, nil, fmt.Errorf("failed to create certificate: %v", err)
return nil, nil, fmt.Errorf("failed to create certificate: %w", err)
}
certBuf := &bytes.Buffer{}
err = pem.Encode(certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if err != nil {
return nil, nil, fmt.Errorf("failed to encode certificate: %v", err)
return nil, nil, fmt.Errorf("failed to encode certificate: %w", err)
}
keybytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal private key: %v", err)
return nil, nil, fmt.Errorf("failed to marshal private key: %w", err)
}
keyBuf := &bytes.Buffer{}
err = pem.Encode(keyBuf, &pem.Block{Type: "PRIVATE KEY", Bytes: keybytes})
if err != nil {
return nil, nil, fmt.Errorf("failed to encode private key: %v", err)
return nil, nil, fmt.Errorf("failed to encode private key: %w", err)
}
return certBuf.Bytes(), keyBuf.Bytes(), nil

View File

@ -1,4 +1,4 @@
// Copyright (c) 2020-2021 The Decred developers
// Copyright (c) 2020-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -206,7 +206,7 @@ func randomX509SerialNumber() (*big.Int, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, fmt.Errorf("failed to generate serial number: %s", err)
return nil, fmt.Errorf("failed to generate serial number: %w", err)
}
return serialNumber, nil
}
@ -277,7 +277,7 @@ func generateAuthority(pub, priv interface{}, hosts []string, org string, years
buf := new(bytes.Buffer)
err = pem.Encode(buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
if err != nil {
return nil, fmt.Errorf("failed to encode certificate: %v", err)
return nil, fmt.Errorf("failed to encode certificate: %w", err)
}
pemBlock := buf.Bytes()
@ -317,7 +317,7 @@ func createIssuedCert(pub, caPriv interface{}, ca *x509.Certificate,
buf := new(bytes.Buffer)
err = pem.Encode(buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
if err != nil {
return nil, fmt.Errorf("failed to encode certificate: %v", err)
return nil, fmt.Errorf("failed to encode certificate: %w", err)
}
pemBlock := buf.Bytes()
@ -336,12 +336,12 @@ func createIssuedCert(pub, caPriv interface{}, ca *x509.Certificate,
func marshalPrivateKey(key interface{}) ([]byte, error) {
der, err := x509.MarshalPKCS8PrivateKey(key)
if err != nil {
return nil, fmt.Errorf("failed to marshal private key: %v", err)
return nil, fmt.Errorf("failed to marshal private key: %w", err)
}
buf := new(bytes.Buffer)
err = pem.Encode(buf, &pem.Block{Type: "PRIVATE KEY", Bytes: der})
if err != nil {
return nil, fmt.Errorf("failed to encode private key: %v", err)
return nil, fmt.Errorf("failed to encode private key: %w", err)
}
return buf.Bytes(), nil
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013, 2014 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -62,7 +62,7 @@ func VerifyMessage(address string, signature string, message string, params Addr
// Decode base64 signature.
sig, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return fmt.Errorf("malformed base64 encoding: %v", err)
return fmt.Errorf("malformed base64 encoding: %w", err)
}
// Validate the signature - this just shows that it was valid for any pubkey

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021-2022 The Decred developers
// Copyright (c) 2021-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -73,14 +73,14 @@ func TestConvertLdbErr(t *testing.T) {
gotErr := convertLdbErr(test.ldbErr, test.desc)
// Validate the error kind.
if gotErr.Err != test.want {
if !errors.Is(gotErr.Err, test.want) {
t.Errorf("%q: mismatched error kind:\nwant: %v\n got: %v\n",
test.name, test.want, gotErr.Err)
continue
}
wantDesc := fmt.Sprintf("%s: %v", test.desc, test.ldbErr)
// Validate the error description.
wantDesc := fmt.Sprintf("%s: %v", test.desc, test.ldbErr)
if gotErr.Description != wantDesc {
t.Errorf("%q: mismatched error description:\nwant: %v\n got: %v\n",
test.name, wantDesc, gotErr.Description)
@ -88,7 +88,7 @@ func TestConvertLdbErr(t *testing.T) {
}
// Validate the raw error.
if gotErr.RawErr != test.ldbErr {
if !errors.Is(gotErr.RawErr, test.ldbErr) {
t.Errorf("%q: mismatched raw error:\nwant: %v\n got: %v\n",
test.name, test.ldbErr, gotErr.RawErr)
continue

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018-2022 The Decred developers
// Copyright (c) 2018-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -228,13 +228,13 @@ func NewEstimator(cfg *EstimatorConfig) (*Estimator, error) {
if cfg.DatabaseFile != "" {
db, err := leveldb.OpenFile(cfg.DatabaseFile, nil)
if err != nil {
return nil, fmt.Errorf("error opening estimator database: %v", err)
return nil, fmt.Errorf("error opening estimator database: %w", err)
}
res.db = db
err = res.loadFromDatabase(cfg.ReplaceBucketsOnLoad)
if err != nil {
return nil, fmt.Errorf("error loading estimator data from db: %v",
return nil, fmt.Errorf("error loading estimator data from db: %w",
err)
}
}
@ -307,7 +307,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
version, err := stats.db.Get(dbKeyVersion, nil)
if err != nil && !errors.Is(err, leveldb.ErrNotFound) {
return fmt.Errorf("error reading version from db: %v", err)
return fmt.Errorf("error reading version from db: %w", err)
}
if len(version) < 1 {
// No data in the file. Fill with the current config.
@ -326,19 +326,19 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
err := binary.Write(b, dbByteOrder, stats.bucketFeeBounds)
if err != nil {
return fmt.Errorf("error writing bucket fees to db: %v", err)
return fmt.Errorf("error writing bucket fees to db: %w", err)
}
batch.Put(dbKeyBucketFees, b.Bytes())
err = stats.db.Write(batch, nil)
if err != nil {
return fmt.Errorf("error writing initial estimator db file: %v",
return fmt.Errorf("error writing initial estimator db file: %w",
err)
}
err = stats.updateDatabase()
if err != nil {
return fmt.Errorf("error adding initial estimator data to db: %v",
return fmt.Errorf("error adding initial estimator data to db: %w",
err)
}
@ -354,7 +354,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
maxConfirmsBytes, err := stats.db.Get(dbKeyMaxConfirms, nil)
if err != nil {
return fmt.Errorf("error reading max confirmation range from db file: "+
"%v", err)
"%w", err)
}
if len(maxConfirmsBytes) != 4 {
return errors.New("wrong number of bytes in stored maxConfirms")
@ -367,7 +367,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
feesBytes, err := stats.db.Get(dbKeyBucketFees, nil)
if err != nil {
return fmt.Errorf("error reading fee bounds from db file: %v", err)
return fmt.Errorf("error reading fee bounds from db file: %w", err)
}
if feesBytes == nil {
return errors.New("fee bounds not found in database file")
@ -381,7 +381,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
err = binary.Read(bytes.NewReader(feesBytes), dbByteOrder,
&fileBucketFees)
if err != nil {
return fmt.Errorf("error decoding file bucket fees: %v", err)
return fmt.Errorf("error decoding file bucket fees: %w", err)
}
if !replaceBuckets {
@ -450,7 +450,7 @@ func (stats *Estimator) loadFromDatabase(replaceBuckets bool) error {
}
err = iter.Error()
if err != nil {
return fmt.Errorf("error on bucket iterator: %v", err)
return fmt.Errorf("error on bucket iterator: %w", err)
}
stats.bucketFeeBounds = fileBucketFees
@ -502,8 +502,7 @@ func (stats *Estimator) updateDatabase() error {
err := stats.db.Write(batch, nil)
if err != nil {
return fmt.Errorf("error writing update to estimator db file: %v",
err)
return fmt.Errorf("error writing update to estimator db file: %w", err)
}
return nil

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021 The Decred developers
// Copyright (c) 2021-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -119,7 +119,7 @@ func (bm *BanManager) AddPeer(p *peer.Peer) error {
host, _, err := net.SplitHostPort(p.Addr())
if err != nil {
p.Disconnect()
return fmt.Errorf("cannot split hostport %v", err)
return fmt.Errorf("cannot split hostport %w", err)
}
bm.mtx.Lock()

View File

@ -759,7 +759,7 @@ func (c *Client) handleSendPostMessage(details *sendPostDetails) {
respBytes, err := io.ReadAll(httpResponse.Body)
httpResponse.Body.Close()
if err != nil {
err = fmt.Errorf("error reading json reply: %v", err)
err = fmt.Errorf("error reading json reply: %w", err)
jReq.responseChan <- &response{err: err}
return
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -183,13 +183,13 @@ func startService() error {
service, err := serviceManager.OpenService(svcName)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
return fmt.Errorf("could not access service: %w", err)
}
defer service.Close()
err = service.Start(os.Args...)
if err != nil {
return fmt.Errorf("could not start service: %v", err)
return fmt.Errorf("could not start service: %w", err)
}
return nil
@ -208,13 +208,13 @@ func controlService(c svc.Cmd, to svc.State) error {
service, err := serviceManager.OpenService(svcName)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
return fmt.Errorf("could not access service: %w", err)
}
defer service.Close()
status, err := service.Control(c)
if err != nil {
return fmt.Errorf("could not send control=%d: %v", c, err)
return fmt.Errorf("could not send control=%d: %w", c, err)
}
// Send the control message.
@ -227,8 +227,7 @@ func controlService(c svc.Cmd, to svc.State) error {
time.Sleep(300 * time.Millisecond)
status, err = service.Query()
if err != nil {
return fmt.Errorf("could not retrieve service "+
"status: %v", err)
return fmt.Errorf("could not retrieve service status: %w", err)
}
}

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -48,14 +48,14 @@ func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
}
sig, err := priv.Sign(hash)
if err != nil {
return nil, fmt.Errorf("cannot sign tx input: %s", err)
return nil, fmt.Errorf("cannot sign tx input: %w", err)
}
sigBytes = sig.Serialize()
case dcrec.STSchnorrSecp256k1:
priv := secp256k1.PrivKeyFromBytes(key)
sig, err := schnorr.Sign(priv, hash)
if err != nil {
return nil, fmt.Errorf("cannot sign tx input: %s", err)
return nil, fmt.Errorf("cannot sign tx input: %w", err)
}
sigBytes = sig.Serialize()
default:
@ -645,7 +645,7 @@ func TSpendSignatureScript(msgTx *wire.MsgTx, privKey []byte) ([]byte, error) {
priv := secp256k1.PrivKeyFromBytes(privKey)
sig, err := schnorr.Sign(priv, hash)
if err != nil {
return nil, fmt.Errorf("cannot sign tx input: %s", err)
return nil, fmt.Errorf("cannot sign tx input: %w", err)
}
sigBytes := sig.Serialize()
pkBytes := priv.PubKey().SerializeCompressed()

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -103,14 +103,12 @@ func checkScripts(msg string, tx *wire.MsgTx, idx int, sigScript, pkScript []byt
var scriptFlags txscript.ScriptFlags
vm, err := txscript.NewEngine(pkScript, tx, idx, scriptFlags, 0, nil)
if err != nil {
return fmt.Errorf("failed to make script engine for %s: %v",
msg, err)
return fmt.Errorf("failed to make script engine for %s: %w", msg, err)
}
err = vm.Execute()
if err != nil {
return fmt.Errorf("invalid script signature for %s: %v", msg,
err)
return fmt.Errorf("invalid script signature for %s: %w", msg, err)
}
return nil
@ -123,7 +121,7 @@ func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
sigScript, err := SignTxOutput(testingParams, tx, idx, pkScript,
hashType, kdb, sdb, nil, isTreasuryEnabled)
if err != nil {
return fmt.Errorf("failed to sign output %s: %v", msg, err)
return fmt.Errorf("failed to sign output %s: %w", msg, err)
}
return checkScripts(msg, tx, idx, sigScript, pkScript)
@ -140,7 +138,7 @@ func signBadAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
sigScript, err := SignTxOutput(testingParams, tx,
idx, pkScript, hashType, kdb, sdb, nil, isTreasuryEnabled)
if err != nil {
return fmt.Errorf("failed to sign output %s: %v", msg, err)
return fmt.Errorf("failed to sign output %s: %w", msg, err)
}
// Be sure to reset the value in when we're done creating the

View File

@ -1,5 +1,5 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Copyright (c) 2015-2020 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
@ -222,8 +222,8 @@ func (m MessageError) Error() string {
}
// messageError creates an Error given a set of arguments.
func messageError(Func string, c ErrorCode, desc string) *MessageError {
return &MessageError{Func: Func, ErrorCode: c, Description: desc}
func messageError(funcName string, c ErrorCode, desc string) *MessageError {
return &MessageError{Func: funcName, ErrorCode: c, Description: desc}
}
// Is implements the interface to work with the standard library's errors.Is.