From e43b5ce5e59b5717a9819ff81805dd431f710c10 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 4 Nov 2021 10:12:57 +0000 Subject: [PATCH] Remove github.com/pkg/errors and replace with std library version This is possible now that we no longer support go1.12 and brings rclone into line with standard practices in the Go world. This also removes errors.New and errors.Errorf from lib/errors and prefers the stdlib errors package over lib/errors. --- CONTRIBUTING.md | 2 +- backend/amazonclouddrive/amazonclouddrive.go | 8 +- backend/azureblob/azureblob.go | 54 ++++---- backend/azureblob/imds.go | 7 +- backend/b2/b2.go | 34 ++--- backend/b2/upload.go | 7 +- backend/box/box.go | 54 ++++---- backend/box/upload.go | 16 +-- backend/cache/cache.go | 48 +++---- backend/cache/cache_internal_test.go | 36 ++--- backend/cache/handle.go | 6 +- backend/cache/object.go | 14 +- backend/cache/storage_memory.go | 4 +- backend/cache/storage_persistent.go | 83 ++++++------ backend/chunker/chunker.go | 28 ++-- backend/compress/compress.go | 20 +-- backend/crypt/cipher.go | 8 +- backend/crypt/cipher_test.go | 4 +- backend/crypt/crypt.go | 32 ++--- backend/crypt/pkcs7/pkcs7.go | 2 +- backend/drive/drive.go | 114 ++++++++-------- backend/drive/drive_internal_test.go | 2 +- backend/dropbox/batcher.go | 18 +-- backend/dropbox/dropbox.go | 58 ++++---- backend/fichier/api.go | 33 ++--- backend/fichier/fichier.go | 14 +- backend/fichier/object.go | 5 +- backend/filefabric/filefabric.go | 38 +++--- backend/ftp/ftp.go | 63 ++++----- .../googlecloudstorage/googlecloudstorage.go | 18 +-- backend/googlephotos/googlephotos.go | 32 ++--- backend/googlephotos/pattern.go | 9 +- backend/hasher/commands.go | 9 +- backend/hasher/hasher.go | 6 +- backend/hasher/kv.go | 6 +- backend/hasher/object.go | 2 +- backend/http/http.go | 29 ++-- backend/hubic/hubic.go | 8 +- backend/jottacloud/api/types.go | 3 +- backend/jottacloud/jottacloud.go | 48 +++---- backend/local/about_unix.go | 4 +- backend/local/about_windows.go | 4 +- backend/local/local.go | 30 ++--- backend/mailru/api/helpers.go | 2 +- backend/mailru/mailru.go | 14 +- backend/mega/mega.go | 77 +++++------ backend/memory/memory.go | 3 +- backend/onedrive/onedrive.go | 42 +++--- backend/opendrive/opendrive.go | 24 ++-- backend/pcloud/pcloud.go | 20 +-- backend/premiumizeme/premiumizeme.go | 60 ++++----- backend/putio/fs.go | 10 +- backend/putio/object.go | 4 +- backend/qingstor/qingstor.go | 14 +- backend/qingstor/upload.go | 6 +- backend/s3/s3.go | 46 +++---- backend/seafile/seafile.go | 14 +- backend/seafile/webapi.go | 58 ++++---- backend/sftp/sftp.go | 126 +++++++++--------- backend/sharefile/api/types.go | 5 +- backend/sharefile/sharefile.go | 60 ++++----- backend/sharefile/upload.go | 7 +- backend/sia/sia.go | 13 +- backend/sugarsync/sugarsync.go | 30 ++--- backend/swift/swift.go | 12 +- backend/tardigrade/fs.go | 20 +-- backend/tardigrade/object.go | 2 +- backend/union/entry.go | 8 +- backend/union/policy/policy.go | 4 +- backend/union/union.go | 42 +++--- backend/union/upstream/upstream.go | 7 +- backend/uptobox/uptobox.go | 46 +++---- backend/webdav/odrvcookie/fetch.go | 13 +- backend/webdav/webdav.go | 38 +++--- backend/yandex/yandex.go | 34 ++--- backend/zoho/zoho.go | 36 ++--- bin/not-in-stable.go | 0 cmd/about/about.go | 6 +- cmd/backend/backend.go | 9 +- cmd/bisync/bisync_test.go | 10 +- cmd/bisync/cmd.go | 13 +- cmd/bisync/deltas.go | 6 +- cmd/bisync/listing.go | 5 +- cmd/bisync/operations.go | 15 ++- cmd/bisync/rc.go | 2 +- cmd/cachestats/cachestats.go | 3 +- cmd/cmd.go | 14 +- cmd/cmount/fs.go | 5 +- cmd/cmount/mount.go | 6 +- cmd/cmount/mount_brew.go | 3 +- cmd/cmount/mountpoint_other.go | 5 +- cmd/cmount/mountpoint_windows.go | 9 +- cmd/config/config.go | 10 +- cmd/cryptcheck/cryptcheck.go | 12 +- cmd/deletefile/deletefile.go | 4 +- cmd/hashsum/hashsum.go | 4 +- cmd/lsf/lsf.go | 3 +- cmd/lsjson/lsjson.go | 9 +- cmd/mount/dir.go | 4 +- cmd/mount/fs.go | 5 +- cmd/mount2/fs.go | 5 +- cmd/mountlib/check_linux.go | 13 +- cmd/mountlib/check_other.go | 8 +- cmd/mountlib/mount.go | 8 +- cmd/mountlib/rc.go | 2 +- cmd/mountlib/utils.go | 4 +- cmd/ncdu/ncdu.go | 11 +- cmd/ncdu/scan/scan.go | 6 +- cmd/rc/rc.go | 28 ++-- cmd/selfupdate/selfupdate.go | 16 +-- cmd/selfupdate/verify.go | 2 +- cmd/serve/dlna/cds.go | 2 +- cmd/serve/dlna/data/data.go | 8 +- cmd/serve/docker/driver.go | 14 +- cmd/serve/docker/options.go | 16 +-- cmd/serve/docker/volume.go | 10 +- cmd/serve/ftp/ftp.go | 2 +- cmd/serve/http/data/data.go | 10 +- cmd/serve/httplib/httplib.go | 3 +- cmd/serve/proxy/proxy.go | 17 +-- cmd/serve/restic/restic.go | 4 +- cmd/serve/sftp/connection.go | 22 +-- cmd/serve/sftp/server.go | 18 +-- cmd/serve/webdav/webdav.go | 5 +- cmd/settier/settier.go | 4 +- cmd/test/info/info.go | 3 +- cmd/touch/touch.go | 13 +- cmd/tree/tree.go | 7 +- cmd/version/version.go | 2 +- fs/accounting/accounting.go | 2 +- fs/accounting/stats_test.go | 3 +- fs/accounting/token_bucket.go | 5 +- fs/asyncreader/asyncreader.go | 2 +- fs/backend_config.go | 10 +- fs/bwtimetable.go | 19 ++- fs/config.go | 3 +- fs/config/authorize.go | 5 +- fs/config/config.go | 14 +- fs/config/configfile/configfile.go | 18 +-- fs/config/configmap/configmap.go | 9 +- fs/config/configstruct/configstruct.go | 6 +- fs/config/crypt.go | 34 ++--- fs/config/obscure/obscure.go | 12 +- fs/config/rc.go | 2 +- fs/config/ui.go | 4 +- fs/countsuffix.go | 7 +- fs/cutoffmode.go | 6 +- fs/dirtree/dirtree.go | 5 +- fs/dump.go | 4 +- fs/filter/filter.go | 4 +- fs/filter/glob.go | 17 ++- fs/fs.go | 3 +- fs/fs_test.go | 2 +- fs/fserrors/enospc_error.go | 4 +- fs/fserrors/error.go | 59 ++++---- fs/fserrors/error_test.go | 38 +++++- fs/hash/hash.go | 6 +- fs/list/list.go | 4 +- fs/log.go | 5 +- fs/march/march.go | 5 +- fs/mount_helper.go | 7 +- fs/open_options.go | 2 +- fs/operations/check.go | 33 ++--- fs/operations/check_test.go | 2 +- fs/operations/dedupe.go | 11 +- fs/operations/lsjson.go | 13 +- fs/operations/multithread.go | 23 ++-- fs/operations/operations.go | 64 ++++----- fs/operations/operations_test.go | 6 +- fs/operations/rc.go | 14 +- fs/operations/reopen.go | 2 +- fs/operations/reopen_test.go | 2 +- fs/rc/config.go | 8 +- fs/rc/config_test.go | 2 +- fs/rc/internal.go | 8 +- fs/rc/jobs/job.go | 6 +- fs/rc/jobs/job_test.go | 2 +- fs/rc/js/main.go | 14 +- fs/rc/params.go | 34 +++-- fs/rc/params_test.go | 2 +- fs/rc/rcserver/rcserver.go | 19 ++- fs/rc/webgui/plugins.go | 2 +- fs/rc/webgui/webgui.go | 12 +- fs/registry.go | 3 +- fs/sizesuffix.go | 11 +- fs/sync/pipe.go | 10 +- fs/sync/sync.go | 4 +- fs/sync/sync_test.go | 6 +- fs/tristate.go | 4 +- fs/walk/walk.go | 9 +- fs/walk/walk_test.go | 2 +- fstest/fstests/fstests.go | 12 +- fstest/test_all/clean.go | 6 +- fstest/test_all/config.go | 6 +- fstest/testserver/testserver.go | 6 +- go.mod | 1 - lib/daemonize/daemon_other.go | 5 +- lib/dircache/dircache.go | 4 +- lib/errors/errors.go | 14 -- lib/errors/errors_test.go | 5 +- lib/file/preallocate_windows.go | 10 +- lib/http/http.go | 2 +- lib/jwtutil/jwtutil.go | 17 +-- lib/kv/bolt.go | 4 +- lib/kv/types.go | 3 +- lib/mmap/mmap_unix.go | 7 +- lib/mmap/mmap_windows.go | 6 +- lib/oauthutil/oauthutil.go | 20 +-- lib/pacer/pacer.go | 4 +- lib/pacer/pacer_test.go | 2 +- lib/random/random.go | 9 +- lib/readers/error_test.go | 2 +- lib/readers/noclose_test.go | 2 +- lib/readers/pattern_reader.go | 3 +- lib/readers/repeatable.go | 3 +- lib/rest/rest.go | 19 +-- lib/rest/url.go | 5 +- librclone/librclone/librclone.go | 9 +- vfs/dir.go | 11 +- vfs/file.go | 5 +- vfs/rc.go | 26 ++-- vfs/read.go | 7 +- vfs/read_write.go | 5 +- vfs/read_write_test.go | 4 +- vfs/vfs_test.go | 4 +- vfs/vfscache/cache.go | 32 ++--- vfs/vfscache/downloaders/downloaders.go | 15 ++- vfs/vfscache/item.go | 54 ++++---- vfs/vfscache/writeback/writeback.go | 4 +- vfs/vfscache/writeback/writeback_test.go | 2 +- vfs/vfscommon/cachemode.go | 5 +- vfs/vfsflags/filemode.go | 4 +- vfs/write_test.go | 8 +- 233 files changed, 1673 insertions(+), 1695 deletions(-) mode change 100755 => 100644 backend/drive/drive.go mode change 100755 => 100644 backend/dropbox/dropbox.go mode change 100755 => 100644 backend/onedrive/onedrive.go mode change 100755 => 100644 bin/not-in-stable.go diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e58e2d79a..f299a4691 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -382,7 +382,7 @@ and `go.sum` in the same commit as your other changes. If you need to update a dependency then run - GO111MODULE=on go get -u github.com/pkg/errors + GO111MODULE=on go get -u golang.org/x/crypto Check in a single commit as above. diff --git a/backend/amazonclouddrive/amazonclouddrive.go b/backend/amazonclouddrive/amazonclouddrive.go index c1dcf80df..58a14427b 100644 --- a/backend/amazonclouddrive/amazonclouddrive.go +++ b/backend/amazonclouddrive/amazonclouddrive.go @@ -14,6 +14,7 @@ we ignore assets completely! import ( "context" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -22,7 +23,6 @@ import ( "time" acd "github.com/ncw/go-acd" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -259,7 +259,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } oAuthClient, ts, err := oauthutil.NewClientWithBaseClient(ctx, name, m, acdConfig, baseClient) if err != nil { - return nil, errors.Wrap(err, "failed to configure Amazon Drive") + return nil, fmt.Errorf("failed to configure Amazon Drive: %w", err) } c := acd.NewClient(oAuthClient) @@ -292,13 +292,13 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get endpoints") + return nil, fmt.Errorf("failed to get endpoints: %w", err) } // Get rootID rootInfo, err := f.getRootInfo(ctx) if err != nil || rootInfo.Id == nil { - return nil, errors.Wrap(err, "failed to get root") + return nil, fmt.Errorf("failed to get root: %w", err) } f.trueRootID = *rootInfo.Id diff --git a/backend/azureblob/azureblob.go b/backend/azureblob/azureblob.go index 966bf264b..74d5ea0e9 100644 --- a/backend/azureblob/azureblob.go +++ b/backend/azureblob/azureblob.go @@ -10,6 +10,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -24,7 +25,6 @@ import ( "github.com/Azure/azure-pipeline-go/pipeline" "github.com/Azure/azure-storage-blob-go/azblob" "github.com/Azure/go-autorest/autorest/adal" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -414,10 +414,10 @@ func (f *Fs) shouldRetry(ctx context.Context, err error) (bool, error) { func checkUploadChunkSize(cs fs.SizeSuffix) error { const minChunkSize = fs.SizeSuffixBase if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } if cs > maxChunkSize { - return errors.Errorf("%s is greater than %s", cs, maxChunkSize) + return fmt.Errorf("%s is greater than %s", cs, maxChunkSize) } return nil } @@ -459,11 +459,11 @@ const azureStorageEndpoint = "https://storage.azure.com/" func newServicePrincipalTokenRefresher(ctx context.Context, credentialsData []byte) (azblob.TokenRefresher, error) { var spCredentials servicePrincipalCredentials if err := json.Unmarshal(credentialsData, &spCredentials); err != nil { - return nil, errors.Wrap(err, "error parsing credentials from JSON file") + return nil, fmt.Errorf("error parsing credentials from JSON file: %w", err) } oauthConfig, err := adal.NewOAuthConfig(azureActiveDirectoryEndpoint, spCredentials.Tenant) if err != nil { - return nil, errors.Wrap(err, "error creating oauth config") + return nil, fmt.Errorf("error creating oauth config: %w", err) } // Create service principal token for Azure Storage. @@ -473,7 +473,7 @@ func newServicePrincipalTokenRefresher(ctx context.Context, credentialsData []by spCredentials.Password, azureStorageEndpoint) if err != nil { - return nil, errors.Wrap(err, "error creating service principal token") + return nil, fmt.Errorf("error creating service principal token: %w", err) } // Wrap token inside a refresher closure. @@ -526,10 +526,10 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "azure: chunk size") + return nil, fmt.Errorf("azure: chunk size: %w", err) } if opt.ListChunkSize > maxListChunkSize { - return nil, errors.Errorf("azure: blob list size can't be greater than %v - was %v", maxListChunkSize, opt.ListChunkSize) + return nil, fmt.Errorf("azure: blob list size can't be greater than %v - was %v", maxListChunkSize, opt.ListChunkSize) } if opt.Endpoint == "" { opt.Endpoint = storageDefaultBaseURL @@ -538,12 +538,12 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.AccessTier == "" { opt.AccessTier = string(defaultAccessTier) } else if !validateAccessTier(opt.AccessTier) { - return nil, errors.Errorf("Azure Blob: Supported access tiers are %s, %s and %s", + return nil, fmt.Errorf("Azure Blob: Supported access tiers are %s, %s and %s", string(azblob.AccessTierHot), string(azblob.AccessTierCool), string(azblob.AccessTierArchive)) } if !validatePublicAccess((opt.PublicAccess)) { - return nil, errors.Errorf("Azure Blob: Supported public access level are %s and %s", + return nil, fmt.Errorf("Azure Blob: Supported public access level are %s and %s", string(azblob.PublicAccessBlob), string(azblob.PublicAccessContainer)) } @@ -585,11 +585,11 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e case opt.UseEmulator: credential, err := azblob.NewSharedKeyCredential(emulatorAccount, emulatorAccountKey) if err != nil { - return nil, errors.Wrapf(err, "Failed to parse credentials") + return nil, fmt.Errorf("Failed to parse credentials: %w", err) } u, err = url.Parse(emulatorBlobEndpoint) if err != nil { - return nil, errors.Wrap(err, "failed to make azure storage url from account and endpoint") + return nil, fmt.Errorf("failed to make azure storage url from account and endpoint: %w", err) } pipeline := f.newPipeline(credential, azblob.PipelineOptions{Retry: azblob.RetryOptions{TryTimeout: maxTryTimeout}}) serviceURL = azblob.NewServiceURL(*u, pipeline) @@ -631,12 +631,12 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e }) if err != nil { - return nil, errors.Wrapf(err, "Failed to acquire MSI token") + return nil, fmt.Errorf("Failed to acquire MSI token: %w", err) } u, err = url.Parse(fmt.Sprintf("https://%s.%s", opt.Account, opt.Endpoint)) if err != nil { - return nil, errors.Wrap(err, "failed to make azure storage url from account and endpoint") + return nil, fmt.Errorf("failed to make azure storage url from account and endpoint: %w", err) } credential := azblob.NewTokenCredential(token.AccessToken, func(credential azblob.TokenCredential) time.Duration { fs.Debugf(f, "Token refresher called.") @@ -666,19 +666,19 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e case opt.Account != "" && opt.Key != "": credential, err := azblob.NewSharedKeyCredential(opt.Account, opt.Key) if err != nil { - return nil, errors.Wrapf(err, "Failed to parse credentials") + return nil, fmt.Errorf("Failed to parse credentials: %w", err) } u, err = url.Parse(fmt.Sprintf("https://%s.%s", opt.Account, opt.Endpoint)) if err != nil { - return nil, errors.Wrap(err, "failed to make azure storage url from account and endpoint") + return nil, fmt.Errorf("failed to make azure storage url from account and endpoint: %w", err) } pipeline := f.newPipeline(credential, azblob.PipelineOptions{Retry: azblob.RetryOptions{TryTimeout: maxTryTimeout}}) serviceURL = azblob.NewServiceURL(*u, pipeline) case opt.SASURL != "": u, err = url.Parse(opt.SASURL) if err != nil { - return nil, errors.Wrapf(err, "failed to parse SAS URL") + return nil, fmt.Errorf("failed to parse SAS URL: %w", err) } // use anonymous credentials in case of sas url pipeline := f.newPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{Retry: azblob.RetryOptions{TryTimeout: maxTryTimeout}}) @@ -698,17 +698,17 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e // Create a standard URL. u, err = url.Parse(fmt.Sprintf("https://%s.%s", opt.Account, opt.Endpoint)) if err != nil { - return nil, errors.Wrap(err, "failed to make azure storage url from account and endpoint") + return nil, fmt.Errorf("failed to make azure storage url from account and endpoint: %w", err) } // Try loading service principal credentials from file. loadedCreds, err := ioutil.ReadFile(env.ShellExpand(opt.ServicePrincipalFile)) if err != nil { - return nil, errors.Wrap(err, "error opening service principal credentials file") + return nil, fmt.Errorf("error opening service principal credentials file: %w", err) } // Create a token refresher from service principal credentials. tokenRefresher, err := newServicePrincipalTokenRefresher(ctx, loadedCreds) if err != nil { - return nil, errors.Wrap(err, "failed to create a service principal token") + return nil, fmt.Errorf("failed to create a service principal token: %w", err) } options := azblob.PipelineOptions{Retry: azblob.RetryOptions{TryTimeout: maxTryTimeout}} pipe := f.newPipeline(azblob.NewTokenCredential("", tokenRefresher), options) @@ -1324,7 +1324,7 @@ func (o *Object) Hash(ctx context.Context, t hash.Type) (string, error) { } data, err := base64.StdEncoding.DecodeString(o.md5) if err != nil { - return "", errors.Wrapf(err, "Failed to decode Content-MD5: %q", o.md5) + return "", fmt.Errorf("Failed to decode Content-MD5: %q: %w", o.md5, err) } return hex.EncodeToString(data), nil } @@ -1510,7 +1510,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read var offset int64 var count int64 if o.AccessTier() == azblob.AccessTierArchive { - return nil, errors.Errorf("Blob in archive tier, you need to set tier to hot or cool first") + return nil, fmt.Errorf("Blob in archive tier, you need to set tier to hot or cool first") } fs.FixRangeOption(options, o.size) for _, option := range options { @@ -1536,11 +1536,11 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return o.fs.shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to open for download") + return nil, fmt.Errorf("failed to open for download: %w", err) } err = o.decodeMetaDataFromDownloadResponse(downloadResponse) if err != nil { - return nil, errors.Wrap(err, "failed to decode metadata for download") + return nil, fmt.Errorf("failed to decode metadata for download: %w", err) } in = downloadResponse.Body(azblob.RetryReaderOptions{}) return in, nil @@ -1630,7 +1630,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op fs.Debugf(o, "deleting archive tier blob before updating") err = o.Remove(ctx) if err != nil { - return errors.Wrap(err, "failed to delete archive blob before updating") + return fmt.Errorf("failed to delete archive blob before updating: %w", err) } } else { return errCantUpdateArchiveTierBlobs @@ -1723,7 +1723,7 @@ func (o *Object) AccessTier() azblob.AccessTierType { // SetTier performs changing object tier func (o *Object) SetTier(tier string) error { if !validateAccessTier(tier) { - return errors.Errorf("Tier %s not supported by Azure Blob Storage", tier) + return fmt.Errorf("Tier %s not supported by Azure Blob Storage", tier) } // Check if current tier already matches with desired tier @@ -1739,7 +1739,7 @@ func (o *Object) SetTier(tier string) error { }) if err != nil { - return errors.Wrap(err, "Failed to set Blob Tier") + return fmt.Errorf("Failed to set Blob Tier: %w", err) } // Set access tier on local object also, this typically diff --git a/backend/azureblob/imds.go b/backend/azureblob/imds.go index 779e0b118..b23e91d62 100644 --- a/backend/azureblob/imds.go +++ b/backend/azureblob/imds.go @@ -13,7 +13,6 @@ import ( "net/http" "github.com/Azure/go-autorest/autorest/adal" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fshttp" ) @@ -95,7 +94,7 @@ func GetMSIToken(ctx context.Context, identity *userMSI) (adal.Token, error) { httpClient := fshttp.NewClient(ctx) resp, err := httpClient.Do(req) if err != nil { - return result, errors.Wrap(err, "MSI is not enabled on this VM") + return result, fmt.Errorf("MSI is not enabled on this VM: %w", err) } defer func() { // resp and Body should not be nil _, err = io.Copy(ioutil.Discard, resp.Body) @@ -120,7 +119,7 @@ func GetMSIToken(ctx context.Context, identity *userMSI) (adal.Token, error) { b, err := ioutil.ReadAll(resp.Body) if err != nil { - return result, errors.Wrap(err, "Couldn't read IMDS response") + return result, fmt.Errorf("Couldn't read IMDS response: %w", err) } // Remove BOM, if any. azcopy does this so I'm following along. b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) @@ -131,7 +130,7 @@ func GetMSIToken(ctx context.Context, identity *userMSI) (adal.Token, error) { // storage API call. err = json.Unmarshal(b, &result) if err != nil { - return result, errors.Wrap(err, "Couldn't unmarshal IMDS response") + return result, fmt.Errorf("Couldn't unmarshal IMDS response: %w", err) } return result, nil diff --git a/backend/b2/b2.go b/backend/b2/b2.go index 32c38211d..b96feb225 100644 --- a/backend/b2/b2.go +++ b/backend/b2/b2.go @@ -9,6 +9,7 @@ import ( "bytes" "context" "crypto/sha1" + "errors" "fmt" gohash "hash" "io" @@ -19,7 +20,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/b2/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -366,7 +366,7 @@ func errorHandler(resp *http.Response) error { func checkUploadChunkSize(cs fs.SizeSuffix) error { if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -381,7 +381,7 @@ func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) func checkUploadCutoff(opt *Options, cs fs.SizeSuffix) error { if cs < opt.ChunkSize { - return errors.Errorf("%v is less than chunk size %v", cs, opt.ChunkSize) + return fmt.Errorf("%v is less than chunk size %v", cs, opt.ChunkSize) } return nil } @@ -414,11 +414,11 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = checkUploadCutoff(opt, opt.UploadCutoff) if err != nil { - return nil, errors.Wrap(err, "b2: upload cutoff") + return nil, fmt.Errorf("b2: upload cutoff: %w", err) } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "b2: chunk size") + return nil, fmt.Errorf("b2: chunk size: %w", err) } if opt.Account == "" { return nil, errors.New("account not found") @@ -463,7 +463,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = f.authorizeAccount(ctx) if err != nil { - return nil, errors.Wrap(err, "failed to authorize account") + return nil, fmt.Errorf("failed to authorize account: %w", err) } // If this is a key limited to a single bucket, it must exist already if f.rootBucket != "" && f.info.Allowed.BucketID != "" { @@ -472,7 +472,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e return nil, errors.New("bucket that application key is restricted to no longer exists") } if allowedBucket != f.rootBucket { - return nil, errors.Errorf("you must use bucket %q with this application key", allowedBucket) + return nil, fmt.Errorf("you must use bucket %q with this application key", allowedBucket) } f.cache.MarkOK(f.rootBucket) f.setBucketID(f.rootBucket, f.info.Allowed.BucketID) @@ -512,7 +512,7 @@ func (f *Fs) authorizeAccount(ctx context.Context) error { return f.shouldRetryNoReauth(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to authenticate") + return fmt.Errorf("failed to authenticate: %w", err) } f.srv.SetRoot(f.info.APIURL+"/b2api/v1").SetHeader("Authorization", f.info.AuthorizationToken) return nil @@ -558,7 +558,7 @@ func (f *Fs) getUploadURL(ctx context.Context, bucket string) (upload *api.GetUp return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get upload URL") + return nil, fmt.Errorf("failed to get upload URL: %w", err) } return upload, nil } @@ -1048,7 +1048,7 @@ func (f *Fs) makeBucket(ctx context.Context, bucket string) error { } } } - return errors.Wrap(err, "failed to create bucket") + return fmt.Errorf("failed to create bucket: %w", err) } f.setBucketID(bucket, response.ID) f.setBucketType(bucket, response.Type) @@ -1083,7 +1083,7 @@ func (f *Fs) Rmdir(ctx context.Context, dir string) error { return f.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to delete bucket") + return fmt.Errorf("failed to delete bucket: %w", err) } f.clearBucketID(bucket) f.clearBucketType(bucket) @@ -1124,7 +1124,7 @@ func (f *Fs) hide(ctx context.Context, bucket, bucketPath string) error { return nil } } - return errors.Wrapf(err, "failed to hide %q", bucketPath) + return fmt.Errorf("failed to hide %q: %w", bucketPath, err) } return nil } @@ -1145,7 +1145,7 @@ func (f *Fs) deleteByID(ctx context.Context, ID, Name string) error { return f.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrapf(err, "failed to delete %q", Name) + return fmt.Errorf("failed to delete %q: %w", Name, err) } return nil } @@ -1364,7 +1364,7 @@ func (f *Fs) getDownloadAuthorization(ctx context.Context, bucket, remote string return f.shouldRetry(ctx, resp, err) }) if err != nil { - return "", errors.Wrap(err, "failed to get download authorization") + return "", fmt.Errorf("failed to get download authorization: %w", err) } return response.AuthorizationToken, nil } @@ -1669,14 +1669,14 @@ func (file *openFile) Close() (err error) { // Check to see we read the correct number of bytes if file.o.Size() != file.bytes { - return errors.Errorf("object corrupted on transfer - length mismatch (want %d got %d)", file.o.Size(), file.bytes) + return fmt.Errorf("object corrupted on transfer - length mismatch (want %d got %d)", file.o.Size(), file.bytes) } // Check the SHA1 receivedSHA1 := file.o.sha1 calculatedSHA1 := fmt.Sprintf("%x", file.hash.Sum(nil)) if receivedSHA1 != "" && receivedSHA1 != calculatedSHA1 { - return errors.Errorf("object corrupted on transfer - SHA1 mismatch (want %q got %q)", receivedSHA1, calculatedSHA1) + return fmt.Errorf("object corrupted on transfer - SHA1 mismatch (want %q got %q)", receivedSHA1, calculatedSHA1) } return nil @@ -1716,7 +1716,7 @@ func (o *Object) getOrHead(ctx context.Context, method string, options []fs.Open if resp != nil && (resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusBadRequest) { return nil, nil, fs.ErrorObjectNotFound } - return nil, nil, errors.Wrapf(err, "failed to %s for download", method) + return nil, nil, fmt.Errorf("failed to %s for download: %w", method, err) } // NB resp may be Open here - don't return err != nil without closing diff --git a/backend/b2/upload.go b/backend/b2/upload.go index 44092dda4..827d33578 100644 --- a/backend/b2/upload.go +++ b/backend/b2/upload.go @@ -15,7 +15,6 @@ import ( "strings" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/b2/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -102,7 +101,7 @@ func (f *Fs) newLargeUpload(ctx context.Context, o *Object, in io.Reader, src fs parts++ } if parts > maxParts { - return nil, errors.Errorf("%q too big (%d bytes) makes too many parts %d > %d - increase --b2-chunk-size", remote, size, parts, maxParts) + return nil, fmt.Errorf("%q too big (%d bytes) makes too many parts %d > %d - increase --b2-chunk-size", remote, size, parts, maxParts) } sha1SliceSize = parts } @@ -185,7 +184,7 @@ func (up *largeUpload) getUploadURL(ctx context.Context) (upload *api.GetUploadP return up.f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get upload URL") + return nil, fmt.Errorf("failed to get upload URL: %w", err) } } else { upload, up.uploads = up.uploads[0], up.uploads[1:] @@ -406,7 +405,7 @@ func (up *largeUpload) Stream(ctx context.Context, initialUploadBlock []byte) (e up.size += int64(n) if part > maxParts { up.f.putBuf(buf, false) - return errors.Errorf("%q too big (%d bytes so far) makes too many parts %d > %d - increase --b2-chunk-size", up.o, up.size, up.parts, maxParts) + return fmt.Errorf("%q too big (%d bytes so far) makes too many parts %d > %d - increase --b2-chunk-size", up.o, up.size, up.parts, maxParts) } part := part // for the closure diff --git a/backend/box/box.go b/backend/box/box.go index 4281a46ca..bde259cea 100644 --- a/backend/box/box.go +++ b/backend/box/box.go @@ -14,6 +14,7 @@ import ( "crypto/rsa" "encoding/json" "encoding/pem" + "errors" "fmt" "io" "io/ioutil" @@ -26,13 +27,6 @@ import ( "sync/atomic" "time" - "github.com/rclone/rclone/lib/encoder" - "github.com/rclone/rclone/lib/env" - "github.com/rclone/rclone/lib/jwtutil" - - "github.com/youmark/pkcs8" - - "github.com/pkg/errors" "github.com/rclone/rclone/backend/box/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -43,9 +37,13 @@ import ( "github.com/rclone/rclone/fs/fshttp" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/lib/dircache" + "github.com/rclone/rclone/lib/encoder" + "github.com/rclone/rclone/lib/env" + "github.com/rclone/rclone/lib/jwtutil" "github.com/rclone/rclone/lib/oauthutil" "github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/rest" + "github.com/youmark/pkcs8" "golang.org/x/oauth2" "golang.org/x/oauth2/jws" ) @@ -93,7 +91,7 @@ func init() { if ok && boxSubTypeOk && jsonFile != "" && boxSubType != "" { err = refreshJWTToken(ctx, jsonFile, boxSubType, name, m) if err != nil { - return nil, errors.Wrap(err, "failed to configure token with jwt authentication") + return nil, fmt.Errorf("failed to configure token with jwt authentication: %w", err) } // Else, if not using an access token, use oauth2 } else if boxAccessToken == "" || !boxAccessTokenOk { @@ -167,15 +165,15 @@ func refreshJWTToken(ctx context.Context, jsonFile string, boxSubType string, na jsonFile = env.ShellExpand(jsonFile) boxConfig, err := getBoxConfig(jsonFile) if err != nil { - return errors.Wrap(err, "get box config") + return fmt.Errorf("get box config: %w", err) } privateKey, err := getDecryptedPrivateKey(boxConfig) if err != nil { - return errors.Wrap(err, "get decrypted private key") + return fmt.Errorf("get decrypted private key: %w", err) } claims, err := getClaims(boxConfig, boxSubType) if err != nil { - return errors.Wrap(err, "get claims") + return fmt.Errorf("get claims: %w", err) } signingHeaders := getSigningHeaders(boxConfig) queryParams := getQueryParams(boxConfig) @@ -187,11 +185,11 @@ func refreshJWTToken(ctx context.Context, jsonFile string, boxSubType string, na func getBoxConfig(configFile string) (boxConfig *api.ConfigJSON, err error) { file, err := ioutil.ReadFile(configFile) if err != nil { - return nil, errors.Wrap(err, "box: failed to read Box config") + return nil, fmt.Errorf("box: failed to read Box config: %w", err) } err = json.Unmarshal(file, &boxConfig) if err != nil { - return nil, errors.Wrap(err, "box: failed to parse Box config") + return nil, fmt.Errorf("box: failed to parse Box config: %w", err) } return boxConfig, nil } @@ -199,7 +197,7 @@ func getBoxConfig(configFile string) (boxConfig *api.ConfigJSON, err error) { func getClaims(boxConfig *api.ConfigJSON, boxSubType string) (claims *jws.ClaimSet, err error) { val, err := jwtutil.RandomHex(20) if err != nil { - return nil, errors.Wrap(err, "box: failed to generate random string for jti") + return nil, fmt.Errorf("box: failed to generate random string for jti: %w", err) } claims = &jws.ClaimSet{ @@ -240,12 +238,12 @@ func getDecryptedPrivateKey(boxConfig *api.ConfigJSON) (key *rsa.PrivateKey, err block, rest := pem.Decode([]byte(boxConfig.BoxAppSettings.AppAuth.PrivateKey)) if len(rest) > 0 { - return nil, errors.Wrap(err, "box: extra data included in private key") + return nil, fmt.Errorf("box: extra data included in private key: %w", err) } rsaKey, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(boxConfig.BoxAppSettings.AppAuth.Passphrase)) if err != nil { - return nil, errors.Wrap(err, "box: failed to decrypt private key") + return nil, fmt.Errorf("box: failed to decrypt private key: %w", err) } return rsaKey.(*rsa.PrivateKey), nil @@ -403,7 +401,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } if opt.UploadCutoff < minUploadCutoff { - return nil, errors.Errorf("box: upload cutoff (%v) must be greater than equal to %v", opt.UploadCutoff, fs.SizeSuffix(minUploadCutoff)) + return nil, fmt.Errorf("box: upload cutoff (%v) must be greater than equal to %v", opt.UploadCutoff, fs.SizeSuffix(minUploadCutoff)) } root = parsePath(root) @@ -414,7 +412,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.AccessToken == "" { client, ts, err = oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure Box") + return nil, fmt.Errorf("failed to configure Box: %w", err) } } @@ -613,7 +611,7 @@ OUTER: return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } for i := range result.Entries { item := &result.Entries[i] @@ -740,14 +738,14 @@ func (f *Fs) preUploadCheck(ctx context.Context, leaf, directoryID string, size var conflict api.PreUploadCheckConflict err = json.Unmarshal(apiErr.ContextInfo, &conflict) if err != nil { - return "", errors.Wrap(err, "pre-upload check: JSON decode failed") + return "", fmt.Errorf("pre-upload check: JSON decode failed: %w", err) } if conflict.Conflicts.Type != api.ItemTypeFile { - return "", errors.Wrap(err, "pre-upload check: can't overwrite non file with file") + return "", fmt.Errorf("pre-upload check: can't overwrite non file with file: %w", err) } return conflict.Conflicts.ID, nil } - return "", errors.Wrap(err, "pre-upload check") + return "", fmt.Errorf("pre-upload check: %w", err) } return "", nil } @@ -856,7 +854,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } f.dirCache.FlushDir(dir) if err != nil { @@ -900,7 +898,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, srcPath := srcObj.fs.rootSlash() + srcObj.remote dstPath := f.rootSlash() + remote if strings.ToLower(srcPath) == strings.ToLower(dstPath) { - return nil, errors.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) + return nil, fmt.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) } // Create temporary object @@ -984,7 +982,7 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to read user info") + return nil, fmt.Errorf("failed to read user info: %w", err) } // FIXME max upload size would be useful to use in Update usage = &fs.Usage{ @@ -1145,7 +1143,7 @@ func (f *Fs) CleanUp(ctx context.Context) (err error) { }) wg.Wait() if deleteErrors != 0 { - return errors.Errorf("failed to delete %d trash items", deleteErrors) + return fmt.Errorf("failed to delete %d trash items", deleteErrors) } return err } @@ -1205,7 +1203,7 @@ func (o *Object) setMetaData(info *api.Item) (err error) { return fs.ErrorIsDir } if info.Type != api.ItemTypeFile { - return errors.Wrapf(fs.ErrorNotAFile, "%q is %q", o.remote, info.Type) + return fmt.Errorf("%q is %q: %w", o.remote, info.Type, fs.ErrorNotAFile) } o.hasMetaData = true o.size = int64(info.Size) @@ -1341,7 +1339,7 @@ func (o *Object) upload(ctx context.Context, in io.Reader, leaf, directoryID str return err } if result.TotalCount != 1 || len(result.Entries) != 1 { - return errors.Errorf("failed to upload %v - not sure why", o) + return fmt.Errorf("failed to upload %v - not sure why", o) } return o.setMetaData(&result.Entries[0]) } diff --git a/backend/box/upload.go b/backend/box/upload.go index a7ad6cc09..c664cfbf5 100644 --- a/backend/box/upload.go +++ b/backend/box/upload.go @@ -8,6 +8,7 @@ import ( "crypto/sha1" "encoding/base64" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -15,7 +16,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/box/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -140,7 +140,7 @@ outer: } } default: - return nil, errors.Errorf("unknown HTTP status return %q (%d)", resp.Status, resp.StatusCode) + return nil, fmt.Errorf("unknown HTTP status return %q (%d)", resp.Status, resp.StatusCode) } } fs.Debugf(o, "commit multipart upload failed %d/%d - trying again in %d seconds (%s)", tries+1, maxTries, delay, why) @@ -151,7 +151,7 @@ outer: } err = json.Unmarshal(body, &result) if err != nil { - return nil, errors.Wrapf(err, "couldn't decode commit response: %q", body) + return nil, fmt.Errorf("couldn't decode commit response: %q: %w", body, err) } return result, nil } @@ -177,7 +177,7 @@ func (o *Object) uploadMultipart(ctx context.Context, in io.Reader, leaf, direct // Create upload session session, err := o.createUploadSession(ctx, leaf, directoryID, size) if err != nil { - return errors.Wrap(err, "multipart upload create session failed") + return fmt.Errorf("multipart upload create session failed: %w", err) } chunkSize := session.PartSize fs.Debugf(o, "Multipart upload session started for %d parts of size %v", session.TotalParts, fs.SizeSuffix(chunkSize)) @@ -222,7 +222,7 @@ outer: // Read the chunk _, err = io.ReadFull(in, buf) if err != nil { - err = errors.Wrap(err, "multipart upload failed to read source") + err = fmt.Errorf("multipart upload failed to read source: %w", err) break outer } @@ -238,7 +238,7 @@ outer: fs.Debugf(o, "Uploading part %d/%d offset %v/%v part size %v", part+1, session.TotalParts, fs.SizeSuffix(position), fs.SizeSuffix(size), fs.SizeSuffix(chunkSize)) partResponse, err := o.uploadPart(ctx, session.ID, position, size, buf, wrap, options...) if err != nil { - err = errors.Wrap(err, "multipart upload failed to upload part") + err = fmt.Errorf("multipart upload failed to upload part: %w", err) select { case errs <- err: default: @@ -266,11 +266,11 @@ outer: // Finalise the upload session result, err := o.commitUpload(ctx, session.ID, parts, modTime, hash.Sum(nil)) if err != nil { - return errors.Wrap(err, "multipart upload failed to finalize") + return fmt.Errorf("multipart upload failed to finalize: %w", err) } if result.TotalCount != 1 || len(result.Entries) != 1 { - return errors.Errorf("multipart upload failed %v - not sure why", o) + return fmt.Errorf("multipart upload failed %v - not sure why", o) } return o.setMetaData(&result.Entries[0]) } diff --git a/backend/cache/cache.go b/backend/cache/cache.go index 9962406f7..50dd5ce38 100644 --- a/backend/cache/cache.go +++ b/backend/cache/cache.go @@ -5,6 +5,7 @@ package cache import ( "context" + "errors" "fmt" "io" "math" @@ -19,7 +20,6 @@ import ( "syscall" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" @@ -356,7 +356,7 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F return nil, err } if opt.ChunkTotalSize < opt.ChunkSize*fs.SizeSuffix(opt.TotalWorkers) { - return nil, errors.Errorf("don't set cache-chunk-total-size(%v) less than cache-chunk-size(%v) * cache-workers(%v)", + return nil, fmt.Errorf("don't set cache-chunk-total-size(%v) less than cache-chunk-size(%v) * cache-workers(%v)", opt.ChunkTotalSize, opt.ChunkSize, opt.TotalWorkers) } @@ -366,13 +366,13 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F rpath, err := parseRootPath(rootPath) if err != nil { - return nil, errors.Wrapf(err, "failed to clean root path %q", rootPath) + return nil, fmt.Errorf("failed to clean root path %q: %w", rootPath, err) } remotePath := fspath.JoinRootPath(opt.Remote, rootPath) wrappedFs, wrapErr := cache.Get(ctx, remotePath) if wrapErr != nil && wrapErr != fs.ErrorIsFile { - return nil, errors.Wrapf(wrapErr, "failed to make remote %q to wrap", remotePath) + return nil, fmt.Errorf("failed to make remote %q to wrap: %w", remotePath, wrapErr) } var fsErr error fs.Debugf(name, "wrapped %v:%v at root %v", wrappedFs.Name(), wrappedFs.Root(), rpath) @@ -401,7 +401,7 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F if opt.PlexToken != "" { f.plexConnector, err = newPlexConnectorWithToken(f, opt.PlexURL, opt.PlexToken, opt.PlexInsecure) if err != nil { - return nil, errors.Wrapf(err, "failed to connect to the Plex API %v", opt.PlexURL) + return nil, fmt.Errorf("failed to connect to the Plex API %v: %w", opt.PlexURL, err) } } else { if opt.PlexPassword != "" && opt.PlexUsername != "" { @@ -413,7 +413,7 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F m.Set("plex_token", token) }) if err != nil { - return nil, errors.Wrapf(err, "failed to connect to the Plex API %v", opt.PlexURL) + return nil, fmt.Errorf("failed to connect to the Plex API %v: %w", opt.PlexURL, err) } } } @@ -434,11 +434,11 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F } err = os.MkdirAll(dbPath, os.ModePerm) if err != nil { - return nil, errors.Wrapf(err, "failed to create cache directory %v", dbPath) + return nil, fmt.Errorf("failed to create cache directory %v: %w", dbPath, err) } err = os.MkdirAll(chunkPath, os.ModePerm) if err != nil { - return nil, errors.Wrapf(err, "failed to create cache directory %v", chunkPath) + return nil, fmt.Errorf("failed to create cache directory %v: %w", chunkPath, err) } dbPath = filepath.Join(dbPath, name+".db") @@ -450,7 +450,7 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F DbWaitTime: time.Duration(opt.DbWaitTime), }) if err != nil { - return nil, errors.Wrapf(err, "failed to start cache db") + return nil, fmt.Errorf("failed to start cache db: %w", err) } // Trap SIGINT and SIGTERM to close the DB handle gracefully c := make(chan os.Signal, 1) @@ -484,12 +484,12 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F if f.opt.TempWritePath != "" { err = os.MkdirAll(f.opt.TempWritePath, os.ModePerm) if err != nil { - return nil, errors.Wrapf(err, "failed to create cache directory %v", f.opt.TempWritePath) + return nil, fmt.Errorf("failed to create cache directory %v: %w", f.opt.TempWritePath, err) } f.opt.TempWritePath = filepath.ToSlash(f.opt.TempWritePath) f.tempFs, err = cache.Get(ctx, f.opt.TempWritePath) if err != nil { - return nil, errors.Wrapf(err, "failed to create temp fs: %v", err) + return nil, fmt.Errorf("failed to create temp fs: %v: %w", err, err) } fs.Infof(name, "Upload Temp Rest Time: %v", f.opt.TempWaitTime) fs.Infof(name, "Upload Temp FS: %v", f.opt.TempWritePath) @@ -606,7 +606,7 @@ func (f *Fs) httpStats(ctx context.Context, in rc.Params) (out rc.Params, err er out = make(rc.Params) m, err := f.Stats() if err != nil { - return out, errors.Errorf("error while getting cache stats") + return out, fmt.Errorf("error while getting cache stats") } out["status"] = "ok" out["stats"] = m @@ -633,7 +633,7 @@ func (f *Fs) httpExpireRemote(ctx context.Context, in rc.Params) (out rc.Params, out = make(rc.Params) remoteInt, ok := in["remote"] if !ok { - return out, errors.Errorf("remote is needed") + return out, fmt.Errorf("remote is needed") } remote := remoteInt.(string) withData := false @@ -644,7 +644,7 @@ func (f *Fs) httpExpireRemote(ctx context.Context, in rc.Params) (out rc.Params, remote = f.unwrapRemote(remote) if !f.cache.HasEntry(path.Join(f.Root(), remote)) { - return out, errors.Errorf("%s doesn't exist in cache", remote) + return out, fmt.Errorf("%s doesn't exist in cache", remote) } co := NewObject(f, remote) @@ -653,7 +653,7 @@ func (f *Fs) httpExpireRemote(ctx context.Context, in rc.Params) (out rc.Params, cd := NewDirectory(f, remote) err := f.cache.ExpireDir(cd) if err != nil { - return out, errors.WithMessage(err, "error expiring directory") + return out, fmt.Errorf("error expiring directory: %w", err) } // notify vfs too f.notifyChangeUpstream(cd.Remote(), fs.EntryDirectory) @@ -664,7 +664,7 @@ func (f *Fs) httpExpireRemote(ctx context.Context, in rc.Params) (out rc.Params, // expire the entry err = f.cache.ExpireObject(co, withData) if err != nil { - return out, errors.WithMessage(err, "error expiring file") + return out, fmt.Errorf("error expiring file: %w", err) } // notify vfs too f.notifyChangeUpstream(co.Remote(), fs.EntryObject) @@ -685,24 +685,24 @@ func (f *Fs) rcFetch(ctx context.Context, in rc.Params) (rc.Params, error) { case 1: start, err = strconv.ParseInt(ints[0], 10, 64) if err != nil { - return nil, errors.Errorf("invalid range: %q", part) + return nil, fmt.Errorf("invalid range: %q", part) } end = start + 1 case 2: if ints[0] != "" { start, err = strconv.ParseInt(ints[0], 10, 64) if err != nil { - return nil, errors.Errorf("invalid range: %q", part) + return nil, fmt.Errorf("invalid range: %q", part) } } if ints[1] != "" { end, err = strconv.ParseInt(ints[1], 10, 64) if err != nil { - return nil, errors.Errorf("invalid range: %q", part) + return nil, fmt.Errorf("invalid range: %q", part) } } default: - return nil, errors.Errorf("invalid range: %q", part) + return nil, fmt.Errorf("invalid range: %q", part) } crs = append(crs, chunkRange{start: start, end: end}) } @@ -757,18 +757,18 @@ func (f *Fs) rcFetch(ctx context.Context, in rc.Params) (rc.Params, error) { delete(in, "chunks") crs, err := parseChunks(s) if err != nil { - return nil, errors.Wrap(err, "invalid chunks parameter") + return nil, fmt.Errorf("invalid chunks parameter: %w", err) } var files [][2]string for k, v := range in { if !strings.HasPrefix(k, "file") { - return nil, errors.Errorf("invalid parameter %s=%s", k, v) + return nil, fmt.Errorf("invalid parameter %s=%s", k, v) } switch v := v.(type) { case string: files = append(files, [2]string{v, f.unwrapRemote(v)}) default: - return nil, errors.Errorf("invalid parameter %s=%s", k, v) + return nil, fmt.Errorf("invalid parameter %s=%s", k, v) } } type fileStatus struct { @@ -1124,7 +1124,7 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) ( case fs.Directory: _ = f.cache.AddDir(DirectoryFromOriginal(ctx, f, o)) default: - return errors.Errorf("Unknown object type %T", entry) + return fmt.Errorf("Unknown object type %T", entry) } } diff --git a/backend/cache/cache_internal_test.go b/backend/cache/cache_internal_test.go index 281d92af1..4bea04291 100644 --- a/backend/cache/cache_internal_test.go +++ b/backend/cache/cache_internal_test.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" goflag "flag" "fmt" "io" @@ -22,7 +23,6 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/cache" "github.com/rclone/rclone/backend/crypt" _ "github.com/rclone/rclone/backend/drive" @@ -446,7 +446,7 @@ func TestInternalWrappedFsChangeNotSeen(t *testing.T) { return err } if coSize != expectedSize { - return errors.Errorf("%v <> %v", coSize, expectedSize) + return fmt.Errorf("%v <> %v", coSize, expectedSize) } return nil }, 12, time.Second*10) @@ -502,7 +502,7 @@ func TestInternalMoveWithNotify(t *testing.T) { } if len(li) != 2 { log.Printf("not expected listing /test: %v", li) - return errors.Errorf("not expected listing /test: %v", li) + return fmt.Errorf("not expected listing /test: %v", li) } li, err = runInstance.list(t, rootFs, "test/one") @@ -512,7 +512,7 @@ func TestInternalMoveWithNotify(t *testing.T) { } if len(li) != 0 { log.Printf("not expected listing /test/one: %v", li) - return errors.Errorf("not expected listing /test/one: %v", li) + return fmt.Errorf("not expected listing /test/one: %v", li) } li, err = runInstance.list(t, rootFs, "test/second") @@ -522,21 +522,21 @@ func TestInternalMoveWithNotify(t *testing.T) { } if len(li) != 1 { log.Printf("not expected listing /test/second: %v", li) - return errors.Errorf("not expected listing /test/second: %v", li) + return fmt.Errorf("not expected listing /test/second: %v", li) } if fi, ok := li[0].(os.FileInfo); ok { if fi.Name() != "data.bin" { log.Printf("not expected name: %v", fi.Name()) - return errors.Errorf("not expected name: %v", fi.Name()) + return fmt.Errorf("not expected name: %v", fi.Name()) } } else if di, ok := li[0].(fs.DirEntry); ok { if di.Remote() != "test/second/data.bin" { log.Printf("not expected remote: %v", di.Remote()) - return errors.Errorf("not expected remote: %v", di.Remote()) + return fmt.Errorf("not expected remote: %v", di.Remote()) } } else { log.Printf("unexpected listing: %v", li) - return errors.Errorf("unexpected listing: %v", li) + return fmt.Errorf("unexpected listing: %v", li) } log.Printf("complete listing: %v", li) @@ -591,17 +591,17 @@ func TestInternalNotifyCreatesEmptyParts(t *testing.T) { found = boltDb.HasEntry(path.Join(cfs.Root(), runInstance.encryptRemoteIfNeeded(t, "test"))) if !found { log.Printf("not found /test") - return errors.Errorf("not found /test") + return fmt.Errorf("not found /test") } found = boltDb.HasEntry(path.Join(cfs.Root(), runInstance.encryptRemoteIfNeeded(t, "test"), runInstance.encryptRemoteIfNeeded(t, "one"))) if !found { log.Printf("not found /test/one") - return errors.Errorf("not found /test/one") + return fmt.Errorf("not found /test/one") } found = boltDb.HasEntry(path.Join(cfs.Root(), runInstance.encryptRemoteIfNeeded(t, "test"), runInstance.encryptRemoteIfNeeded(t, "one"), runInstance.encryptRemoteIfNeeded(t, "test2"))) if !found { log.Printf("not found /test/one/test2") - return errors.Errorf("not found /test/one/test2") + return fmt.Errorf("not found /test/one/test2") } li, err := runInstance.list(t, rootFs, "test/one") if err != nil { @@ -610,21 +610,21 @@ func TestInternalNotifyCreatesEmptyParts(t *testing.T) { } if len(li) != 1 { log.Printf("not expected listing /test/one: %v", li) - return errors.Errorf("not expected listing /test/one: %v", li) + return fmt.Errorf("not expected listing /test/one: %v", li) } if fi, ok := li[0].(os.FileInfo); ok { if fi.Name() != "test2" { log.Printf("not expected name: %v", fi.Name()) - return errors.Errorf("not expected name: %v", fi.Name()) + return fmt.Errorf("not expected name: %v", fi.Name()) } } else if di, ok := li[0].(fs.DirEntry); ok { if di.Remote() != "test/one/test2" { log.Printf("not expected remote: %v", di.Remote()) - return errors.Errorf("not expected remote: %v", di.Remote()) + return fmt.Errorf("not expected remote: %v", di.Remote()) } } else { log.Printf("unexpected listing: %v", li) - return errors.Errorf("unexpected listing: %v", li) + return fmt.Errorf("unexpected listing: %v", li) } log.Printf("complete listing /test/one/test2") return nil @@ -1062,7 +1062,7 @@ func (r *run) readDataFromRemote(t *testing.T, f fs.Fs, remote string, offset, e checkSample = r.readDataFromObj(t, co, offset, end, noLengthCheck) if !noLengthCheck && size != int64(len(checkSample)) { - return checkSample, errors.Errorf("read size doesn't match expected: %v <> %v", len(checkSample), size) + return checkSample, fmt.Errorf("read size doesn't match expected: %v <> %v", len(checkSample), size) } return checkSample, nil } @@ -1257,7 +1257,7 @@ func (r *run) listenForBackgroundUpload(t *testing.T, f fs.Fs, remote string) ch case state = <-buCh: // continue case <-time.After(maxDuration): - waitCh <- errors.Errorf("Timed out waiting for background upload: %v", remote) + waitCh <- fmt.Errorf("Timed out waiting for background upload: %v", remote) return } checkRemote := state.Remote @@ -1274,7 +1274,7 @@ func (r *run) listenForBackgroundUpload(t *testing.T, f fs.Fs, remote string) ch return } } - waitCh <- errors.Errorf("Too many attempts to wait for the background upload: %v", remote) + waitCh <- fmt.Errorf("Too many attempts to wait for the background upload: %v", remote) }() return waitCh } diff --git a/backend/cache/handle.go b/backend/cache/handle.go index f39f5f633..a7a1497e1 100644 --- a/backend/cache/handle.go +++ b/backend/cache/handle.go @@ -5,6 +5,7 @@ package cache import ( "context" + "errors" "fmt" "io" "path" @@ -13,7 +14,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/operations" ) @@ -243,7 +243,7 @@ func (r *Handle) getChunk(chunkStart int64) ([]byte, error) { return nil, io.ErrUnexpectedEOF } - return nil, errors.Errorf("chunk not found %v", chunkStart) + return nil, fmt.Errorf("chunk not found %v", chunkStart) } // first chunk will be aligned with the start @@ -323,7 +323,7 @@ func (r *Handle) Seek(offset int64, whence int) (int64, error) { fs.Debugf(r, "moving offset end (%v) from %v to %v", r.cachedObject.Size(), r.offset, r.cachedObject.Size()+offset) r.offset = r.cachedObject.Size() + offset default: - err = errors.Errorf("cache: unimplemented seek whence %v", whence) + err = fmt.Errorf("cache: unimplemented seek whence %v", whence) } chunkStart := r.offset - (r.offset % int64(r.cacheFs().opt.ChunkSize)) diff --git a/backend/cache/object.go b/backend/cache/object.go index adae08970..8dc072017 100644 --- a/backend/cache/object.go +++ b/backend/cache/object.go @@ -5,12 +5,12 @@ package cache import ( "context" + "fmt" "io" "path" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/lib/readers" @@ -178,10 +178,14 @@ func (o *Object) refreshFromSource(ctx context.Context, force bool) error { } if o.isTempFile() { liveObject, err = o.ParentFs.NewObject(ctx, o.Remote()) - err = errors.Wrapf(err, "in parent fs %v", o.ParentFs) + if err != nil { + err = fmt.Errorf("in parent fs %v: %w", o.ParentFs, err) + } } else { liveObject, err = o.CacheFs.Fs.NewObject(ctx, o.Remote()) - err = errors.Wrapf(err, "in cache fs %v", o.CacheFs.Fs) + if err != nil { + err = fmt.Errorf("in cache fs %v: %w", o.CacheFs.Fs, err) + } } if err != nil { fs.Errorf(o, "error refreshing object in : %v", err) @@ -253,7 +257,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op defer o.CacheFs.backgroundRunner.play() // don't allow started uploads if o.isTempFile() && o.tempFileStartedUpload() { - return errors.Errorf("%v is currently uploading, can't update", o) + return fmt.Errorf("%v is currently uploading, can't update", o) } } fs.Debugf(o, "updating object contents with size %v", src.Size()) @@ -292,7 +296,7 @@ func (o *Object) Remove(ctx context.Context) error { defer o.CacheFs.backgroundRunner.play() // don't allow started uploads if o.isTempFile() && o.tempFileStartedUpload() { - return errors.Errorf("%v is currently uploading, can't delete", o) + return fmt.Errorf("%v is currently uploading, can't delete", o) } } err := o.Object.Remove(ctx) diff --git a/backend/cache/storage_memory.go b/backend/cache/storage_memory.go index 8705e9125..8e8a360fc 100644 --- a/backend/cache/storage_memory.go +++ b/backend/cache/storage_memory.go @@ -4,12 +4,12 @@ package cache import ( + "fmt" "strconv" "strings" "time" cache "github.com/patrickmn/go-cache" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -53,7 +53,7 @@ func (m *Memory) GetChunk(cachedObject *Object, offset int64) ([]byte, error) { return data, nil } - return nil, errors.Errorf("couldn't get cached object data at offset %v", offset) + return nil, fmt.Errorf("couldn't get cached object data at offset %v", offset) } // AddChunk adds a new chunk of a cached object diff --git a/backend/cache/storage_persistent.go b/backend/cache/storage_persistent.go index b6d292989..89af35f87 100644 --- a/backend/cache/storage_persistent.go +++ b/backend/cache/storage_persistent.go @@ -17,7 +17,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/walk" bolt "go.etcd.io/bbolt" @@ -120,11 +119,11 @@ func (b *Persistent) connect() error { err = os.MkdirAll(b.dataPath, os.ModePerm) if err != nil { - return errors.Wrapf(err, "failed to create a data directory %q", b.dataPath) + return fmt.Errorf("failed to create a data directory %q: %w", b.dataPath, err) } b.db, err = bolt.Open(b.dbPath, 0644, &bolt.Options{Timeout: b.features.DbWaitTime}) if err != nil { - return errors.Wrapf(err, "failed to open a cache connection to %q", b.dbPath) + return fmt.Errorf("failed to open a cache connection to %q: %w", b.dbPath, err) } if b.features.PurgeDb { b.Purge() @@ -176,7 +175,7 @@ func (b *Persistent) GetDir(remote string) (*Directory, error) { err := b.db.View(func(tx *bolt.Tx) error { bucket := b.getBucket(remote, false, tx) if bucket == nil { - return errors.Errorf("couldn't open bucket (%v)", remote) + return fmt.Errorf("couldn't open bucket (%v)", remote) } data := bucket.Get([]byte(".")) @@ -184,7 +183,7 @@ func (b *Persistent) GetDir(remote string) (*Directory, error) { return json.Unmarshal(data, cd) } - return errors.Errorf("%v not found", remote) + return fmt.Errorf("%v not found", remote) }) return cd, err @@ -209,7 +208,7 @@ func (b *Persistent) AddBatchDir(cachedDirs []*Directory) error { bucket = b.getBucket(cachedDirs[0].Dir, true, tx) } if bucket == nil { - return errors.Errorf("couldn't open bucket (%v)", cachedDirs[0].Dir) + return fmt.Errorf("couldn't open bucket (%v)", cachedDirs[0].Dir) } for _, cachedDir := range cachedDirs { @@ -226,7 +225,7 @@ func (b *Persistent) AddBatchDir(cachedDirs []*Directory) error { encoded, err := json.Marshal(cachedDir) if err != nil { - return errors.Errorf("couldn't marshal object (%v): %v", cachedDir, err) + return fmt.Errorf("couldn't marshal object (%v): %v", cachedDir, err) } err = b.Put([]byte("."), encoded) if err != nil { @@ -244,17 +243,17 @@ func (b *Persistent) GetDirEntries(cachedDir *Directory) (fs.DirEntries, error) err := b.db.View(func(tx *bolt.Tx) error { bucket := b.getBucket(cachedDir.abs(), false, tx) if bucket == nil { - return errors.Errorf("couldn't open bucket (%v)", cachedDir.abs()) + return fmt.Errorf("couldn't open bucket (%v)", cachedDir.abs()) } val := bucket.Get([]byte(".")) if val != nil { err := json.Unmarshal(val, cachedDir) if err != nil { - return errors.Errorf("error during unmarshalling obj: %v", err) + return fmt.Errorf("error during unmarshalling obj: %v", err) } } else { - return errors.Errorf("missing cached dir: %v", cachedDir) + return fmt.Errorf("missing cached dir: %v", cachedDir) } c := bucket.Cursor() @@ -269,7 +268,7 @@ func (b *Persistent) GetDirEntries(cachedDir *Directory) (fs.DirEntries, error) // we try to find a cached meta for the dir currentBucket := c.Bucket().Bucket(k) if currentBucket == nil { - return errors.Errorf("couldn't open bucket (%v)", string(k)) + return fmt.Errorf("couldn't open bucket (%v)", string(k)) } metaKey := currentBucket.Get([]byte(".")) @@ -318,7 +317,7 @@ func (b *Persistent) RemoveDir(fp string) error { err = b.db.Update(func(tx *bolt.Tx) error { bucket := b.getBucket(cleanPath(parentDir), false, tx) if bucket == nil { - return errors.Errorf("couldn't open bucket (%v)", fp) + return fmt.Errorf("couldn't open bucket (%v)", fp) } // delete the cached dir err := bucket.DeleteBucket([]byte(cleanPath(dirName))) @@ -378,13 +377,13 @@ func (b *Persistent) GetObject(cachedObject *Object) (err error) { return b.db.View(func(tx *bolt.Tx) error { bucket := b.getBucket(cachedObject.Dir, false, tx) if bucket == nil { - return errors.Errorf("couldn't open parent bucket for %v", cachedObject.Dir) + return fmt.Errorf("couldn't open parent bucket for %v", cachedObject.Dir) } val := bucket.Get([]byte(cachedObject.Name)) if val != nil { return json.Unmarshal(val, cachedObject) } - return errors.Errorf("couldn't find object (%v)", cachedObject.Name) + return fmt.Errorf("couldn't find object (%v)", cachedObject.Name) }) } @@ -393,16 +392,16 @@ func (b *Persistent) AddObject(cachedObject *Object) error { return b.db.Update(func(tx *bolt.Tx) error { bucket := b.getBucket(cachedObject.Dir, true, tx) if bucket == nil { - return errors.Errorf("couldn't open parent bucket for %v", cachedObject) + return fmt.Errorf("couldn't open parent bucket for %v", cachedObject) } // cache Object Info encoded, err := json.Marshal(cachedObject) if err != nil { - return errors.Errorf("couldn't marshal object (%v) info: %v", cachedObject, err) + return fmt.Errorf("couldn't marshal object (%v) info: %v", cachedObject, err) } err = bucket.Put([]byte(cachedObject.Name), encoded) if err != nil { - return errors.Errorf("couldn't cache object (%v) info: %v", cachedObject, err) + return fmt.Errorf("couldn't cache object (%v) info: %v", cachedObject, err) } return nil }) @@ -414,7 +413,7 @@ func (b *Persistent) RemoveObject(fp string) error { return b.db.Update(func(tx *bolt.Tx) error { bucket := b.getBucket(cleanPath(parentDir), false, tx) if bucket == nil { - return errors.Errorf("couldn't open parent bucket for %v", cleanPath(parentDir)) + return fmt.Errorf("couldn't open parent bucket for %v", cleanPath(parentDir)) } err := bucket.Delete([]byte(cleanPath(objName))) if err != nil { @@ -446,7 +445,7 @@ func (b *Persistent) HasEntry(remote string) bool { err := b.db.View(func(tx *bolt.Tx) error { bucket := b.getBucket(dir, false, tx) if bucket == nil { - return errors.Errorf("couldn't open parent bucket for %v", remote) + return fmt.Errorf("couldn't open parent bucket for %v", remote) } if f := bucket.Bucket([]byte(name)); f != nil { return nil @@ -455,7 +454,7 @@ func (b *Persistent) HasEntry(remote string) bool { return nil } - return errors.Errorf("couldn't find object (%v)", remote) + return fmt.Errorf("couldn't find object (%v)", remote) }) if err == nil { return true @@ -555,7 +554,7 @@ func (b *Persistent) CleanChunksBySize(maxSize int64) { err := b.db.Update(func(tx *bolt.Tx) error { dataTsBucket := tx.Bucket([]byte(DataTsBucket)) if dataTsBucket == nil { - return errors.Errorf("Couldn't open (%v) bucket", DataTsBucket) + return fmt.Errorf("Couldn't open (%v) bucket", DataTsBucket) } // iterate through ts c := dataTsBucket.Cursor() @@ -733,7 +732,7 @@ func (b *Persistent) GetChunkTs(path string, offset int64) (time.Time, error) { return nil } } - return errors.Errorf("not found %v-%v", path, offset) + return fmt.Errorf("not found %v-%v", path, offset) }) return t, err @@ -773,7 +772,7 @@ func (b *Persistent) addPendingUpload(destPath string, started bool) error { return b.db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(tempBucket)) if err != nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } tempObj := &tempUploadInfo{ DestPath: destPath, @@ -784,11 +783,11 @@ func (b *Persistent) addPendingUpload(destPath string, started bool) error { // cache Object Info encoded, err := json.Marshal(tempObj) if err != nil { - return errors.Errorf("couldn't marshal object (%v) info: %v", destPath, err) + return fmt.Errorf("couldn't marshal object (%v) info: %v", destPath, err) } err = bucket.Put([]byte(destPath), encoded) if err != nil { - return errors.Errorf("couldn't cache object (%v) info: %v", destPath, err) + return fmt.Errorf("couldn't cache object (%v) info: %v", destPath, err) } return nil @@ -803,7 +802,7 @@ func (b *Persistent) getPendingUpload(inRoot string, waitTime time.Duration) (de err = b.db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(tempBucket)) if err != nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } c := bucket.Cursor() @@ -836,7 +835,7 @@ func (b *Persistent) getPendingUpload(inRoot string, waitTime time.Duration) (de return nil } - return errors.Errorf("no pending upload found") + return fmt.Errorf("no pending upload found") }) return destPath, err @@ -847,14 +846,14 @@ func (b *Persistent) SearchPendingUpload(remote string) (started bool, err error err = b.db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(tempBucket)) if bucket == nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } var tempObj = &tempUploadInfo{} v := bucket.Get([]byte(remote)) err = json.Unmarshal(v, tempObj) if err != nil { - return errors.Errorf("pending upload (%v) not found %v", remote, err) + return fmt.Errorf("pending upload (%v) not found %v", remote, err) } started = tempObj.Started @@ -869,7 +868,7 @@ func (b *Persistent) searchPendingUploadFromDir(dir string) (remotes []string, e err = b.db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(tempBucket)) if bucket == nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } c := bucket.Cursor() @@ -899,22 +898,22 @@ func (b *Persistent) rollbackPendingUpload(remote string) error { return b.db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(tempBucket)) if err != nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } var tempObj = &tempUploadInfo{} v := bucket.Get([]byte(remote)) err = json.Unmarshal(v, tempObj) if err != nil { - return errors.Errorf("pending upload (%v) not found %v", remote, err) + return fmt.Errorf("pending upload (%v) not found %v", remote, err) } tempObj.Started = false v2, err := json.Marshal(tempObj) if err != nil { - return errors.Errorf("pending upload not updated %v", err) + return fmt.Errorf("pending upload not updated %v", err) } err = bucket.Put([]byte(tempObj.DestPath), v2) if err != nil { - return errors.Errorf("pending upload not updated %v", err) + return fmt.Errorf("pending upload not updated %v", err) } return nil }) @@ -927,7 +926,7 @@ func (b *Persistent) removePendingUpload(remote string) error { return b.db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(tempBucket)) if err != nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } return bucket.Delete([]byte(remote)) }) @@ -942,17 +941,17 @@ func (b *Persistent) updatePendingUpload(remote string, fn func(item *tempUpload return b.db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(tempBucket)) if err != nil { - return errors.Errorf("couldn't bucket for %v", tempBucket) + return fmt.Errorf("couldn't bucket for %v", tempBucket) } var tempObj = &tempUploadInfo{} v := bucket.Get([]byte(remote)) err = json.Unmarshal(v, tempObj) if err != nil { - return errors.Errorf("pending upload (%v) not found %v", remote, err) + return fmt.Errorf("pending upload (%v) not found %v", remote, err) } if tempObj.Started { - return errors.Errorf("pending upload already started %v", remote) + return fmt.Errorf("pending upload already started %v", remote) } err = fn(tempObj) if err != nil { @@ -970,11 +969,11 @@ func (b *Persistent) updatePendingUpload(remote string, fn func(item *tempUpload } v2, err := json.Marshal(tempObj) if err != nil { - return errors.Errorf("pending upload not updated %v", err) + return fmt.Errorf("pending upload not updated %v", err) } err = bucket.Put([]byte(tempObj.DestPath), v2) if err != nil { - return errors.Errorf("pending upload not updated %v", err) + return fmt.Errorf("pending upload not updated %v", err) } return nil @@ -1015,11 +1014,11 @@ func (b *Persistent) ReconcileTempUploads(ctx context.Context, cacheFs *Fs) erro // cache Object Info encoded, err := json.Marshal(tempObj) if err != nil { - return errors.Errorf("couldn't marshal object (%v) info: %v", queuedEntry, err) + return fmt.Errorf("couldn't marshal object (%v) info: %v", queuedEntry, err) } err = bucket.Put([]byte(destPath), encoded) if err != nil { - return errors.Errorf("couldn't cache object (%v) info: %v", destPath, err) + return fmt.Errorf("couldn't cache object (%v) info: %v", destPath, err) } fs.Debugf(cacheFs, "reconciled temporary upload: %v", destPath) } diff --git a/backend/chunker/chunker.go b/backend/chunker/chunker.go index 3d4de1b85..76bed2e6c 100644 --- a/backend/chunker/chunker.go +++ b/backend/chunker/chunker.go @@ -8,6 +8,7 @@ import ( "crypto/sha1" "encoding/hex" "encoding/json" + "errors" "fmt" gohash "hash" "io" @@ -21,7 +22,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/cache" @@ -290,13 +290,13 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, baseName, basePath, err := fspath.SplitFs(remote) if err != nil { - return nil, errors.Wrapf(err, "failed to parse remote %q to wrap", remote) + return nil, fmt.Errorf("failed to parse remote %q to wrap: %w", remote, err) } // Look for a file first remotePath := fspath.JoinRootPath(basePath, rpath) baseFs, err := cache.Get(ctx, baseName+remotePath) if err != fs.ErrorIsFile && err != nil { - return nil, errors.Wrapf(err, "failed to make remote %q to wrap", baseName+remotePath) + return nil, fmt.Errorf("failed to make remote %q to wrap: %w", baseName+remotePath, err) } if !operations.CanServerSideMove(baseFs) { return nil, errors.New("can't use chunker on a backend which doesn't support server-side move or copy") @@ -386,7 +386,7 @@ type Fs struct { // configure must be called only from NewFs or by unit tests. func (f *Fs) configure(nameFormat, metaFormat, hashType, transactionMode string) error { if err := f.setChunkNameFormat(nameFormat); err != nil { - return errors.Wrapf(err, "invalid name format '%s'", nameFormat) + return fmt.Errorf("invalid name format '%s': %w", nameFormat, err) } if err := f.setMetaFormat(metaFormat); err != nil { return err @@ -878,7 +878,7 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { // ignores non-chunked objects and skips chunk size checks. func (f *Fs) scanObject(ctx context.Context, remote string, quickScan bool) (fs.Object, error) { if err := f.forbidChunk(false, remote); err != nil { - return nil, errors.Wrap(err, "can't access") + return nil, fmt.Errorf("can't access: %w", err) } var ( @@ -927,7 +927,7 @@ func (f *Fs) scanObject(ctx context.Context, remote string, quickScan bool) (fs. case fs.ErrorDirNotFound: entries = nil default: - return nil, errors.Wrap(err, "can't detect composite file") + return nil, fmt.Errorf("can't detect composite file: %w", err) } if f.useNoRename { @@ -1067,7 +1067,7 @@ func (o *Object) readMetadata(ctx context.Context) error { case ErrMetaTooBig, ErrMetaUnknown: return err // return these errors unwrapped for unit tests default: - return errors.Wrap(err, "invalid metadata") + return fmt.Errorf("invalid metadata: %w", err) } if o.size != metaInfo.Size() || len(o.chunks) != metaInfo.nChunks { return errors.New("metadata doesn't match file size") @@ -1132,7 +1132,7 @@ func (f *Fs) put( // Perform consistency checks if err := f.forbidChunk(src, remote); err != nil { - return nil, errors.Wrap(err, action+" refused") + return nil, fmt.Errorf("%s refused: %w", action, err) } if target == nil { // Get target object with a quick directory scan @@ -1146,7 +1146,7 @@ func (f *Fs) put( obj := target.(*Object) if err := obj.readMetadata(ctx); err == ErrMetaUnknown { // refuse to update a file of unsupported format - return nil, errors.Wrap(err, "refusing to "+action) + return nil, fmt.Errorf("refusing to %s: %w", action, err) } } @@ -1564,7 +1564,7 @@ func (f *Fs) Hashes() hash.Set { // Shouldn't return an error if it already exists func (f *Fs) Mkdir(ctx context.Context, dir string) error { if err := f.forbidChunk(dir, dir); err != nil { - return errors.Wrap(err, "can't mkdir") + return fmt.Errorf("can't mkdir: %w", err) } return f.base.Mkdir(ctx, dir) } @@ -1633,7 +1633,7 @@ func (o *Object) Remove(ctx context.Context) (err error) { if err := o.f.forbidChunk(o, o.Remote()); err != nil { // operations.Move can still call Remove if chunker's Move refuses // to corrupt file in hard mode. Hence, refuse to Remove, too. - return errors.Wrap(err, "refuse to corrupt") + return fmt.Errorf("refuse to corrupt: %w", err) } if err := o.readMetadata(ctx); err == ErrMetaUnknown { // Proceed but warn user that unexpected things can happen. @@ -1661,12 +1661,12 @@ func (o *Object) Remove(ctx context.Context) (err error) { // copyOrMove implements copy or move func (f *Fs) copyOrMove(ctx context.Context, o *Object, remote string, do copyMoveFn, md5, sha1, opName string) (fs.Object, error) { if err := f.forbidChunk(o, remote); err != nil { - return nil, errors.Wrapf(err, "can't %s", opName) + return nil, fmt.Errorf("can't %s: %w", opName, err) } if err := o.readMetadata(ctx); err != nil { // Refuse to copy/move composite files with invalid or future // metadata format which might involve unsupported chunk types. - return nil, errors.Wrapf(err, "can't %s this file", opName) + return nil, fmt.Errorf("can't %s this file: %w", opName, err) } if !o.isComposite() { fs.Debugf(o, "%s non-chunked object...", opName) @@ -2163,7 +2163,7 @@ func (o *Object) UnWrap() fs.Object { func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (rc io.ReadCloser, err error) { if err := o.readMetadata(ctx); err != nil { // refuse to open unsupported format - return nil, errors.Wrap(err, "can't open") + return nil, fmt.Errorf("can't open: %w", err) } if !o.isComposite() { return o.mainChunk().Open(ctx, options...) // chain to wrapped non-chunked file diff --git a/backend/compress/compress.go b/backend/compress/compress.go index 6fc04a8bd..c7b3a4006 100644 --- a/backend/compress/compress.go +++ b/backend/compress/compress.go @@ -10,6 +10,7 @@ import ( "encoding/binary" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -21,7 +22,6 @@ import ( "github.com/buengese/sgzip" "github.com/gabriel-vasile/mimetype" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/chunkedreader" @@ -143,7 +143,7 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, wInfo, wName, wPath, wConfig, err := fs.ConfigFs(remote) if err != nil { - return nil, errors.Wrapf(err, "failed to parse remote %q to wrap", remote) + return nil, fmt.Errorf("failed to parse remote %q to wrap: %w", remote, err) } // Strip trailing slashes if they exist in rpath @@ -158,7 +158,7 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, wrappedFs, err = wInfo.NewFs(ctx, wName, remotePath, wConfig) } if err != nil && err != fs.ErrorIsFile { - return nil, errors.Wrapf(err, "failed to make remote %s:%q to wrap", wName, remotePath) + return nil, fmt.Errorf("failed to make remote %s:%q to wrap: %w", wName, remotePath, err) } // Create the wrapping fs @@ -304,7 +304,7 @@ func (f *Fs) processEntries(entries fs.DirEntries) (newEntries fs.DirEntries, er case fs.Directory: f.addDir(&newEntries, x) default: - return nil, errors.Errorf("Unknown object type %T", entry) + return nil, fmt.Errorf("Unknown object type %T", entry) } } return newEntries, nil @@ -410,7 +410,7 @@ func (f *Fs) verifyObjectHash(ctx context.Context, o fs.Object, hasher *hash.Mul srcHash := hasher.Sums()[ht] dstHash, err := o.Hash(ctx, ht) if err != nil { - return errors.Wrap(err, "failed to read destination hash") + return fmt.Errorf("failed to read destination hash: %w", err) } if srcHash != "" && dstHash != "" && srcHash != dstHash { // remove object @@ -418,7 +418,7 @@ func (f *Fs) verifyObjectHash(ctx context.Context, o fs.Object, hasher *hash.Mul if err != nil { fs.Errorf(o, "Failed to remove corrupted object: %v", err) } - return errors.Errorf("corrupted on transfer: %v compressed hashes differ %q vs %q", ht, srcHash, dstHash) + return fmt.Errorf("corrupted on transfer: %v compressed hashes differ %q vs %q", ht, srcHash, dstHash) } return nil } @@ -462,10 +462,10 @@ func (f *Fs) rcat(ctx context.Context, dstFileName string, in io.ReadCloser, mod _ = os.Remove(tempFile.Name()) }() if err != nil { - return nil, errors.Wrap(err, "Failed to create temporary local FS to spool file") + return nil, fmt.Errorf("Failed to create temporary local FS to spool file: %w", err) } if _, err = io.Copy(tempFile, in); err != nil { - return nil, errors.Wrap(err, "Failed to write temporary local file") + return nil, fmt.Errorf("Failed to write temporary local file: %w", err) } if _, err = tempFile.Seek(0, 0); err != nil { return nil, err @@ -714,7 +714,7 @@ func (f *Fs) PutStream(ctx context.Context, in io.Reader, src fs.ObjectInfo, opt if found && (oldObj.(*Object).meta.Mode != Uncompressed || compressible) { err = oldObj.(*Object).Object.Remove(ctx) if err != nil { - return nil, errors.Wrap(err, "Could remove original object") + return nil, fmt.Errorf("Could remove original object: %w", err) } } @@ -723,7 +723,7 @@ func (f *Fs) PutStream(ctx context.Context, in io.Reader, src fs.ObjectInfo, opt if compressible { wrapObj, err := operations.Move(ctx, f.Fs, nil, f.dataName(src.Remote(), newObj.size, compressible), newObj.Object) if err != nil { - return nil, errors.Wrap(err, "Couldn't rename streamed Object.") + return nil, fmt.Errorf("Couldn't rename streamed Object.: %w", err) } newObj.Object = wrapObj } diff --git a/backend/crypt/cipher.go b/backend/crypt/cipher.go index de0bbd055..161ccc818 100644 --- a/backend/crypt/cipher.go +++ b/backend/crypt/cipher.go @@ -7,6 +7,7 @@ import ( gocipher "crypto/cipher" "crypto/rand" "encoding/base32" + "errors" "fmt" "io" "strconv" @@ -15,7 +16,6 @@ import ( "time" "unicode/utf8" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt/pkcs7" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -94,7 +94,7 @@ func NewNameEncryptionMode(s string) (mode NameEncryptionMode, err error) { case "obfuscate": mode = NameEncryptionObfuscated default: - err = errors.Errorf("Unknown file name encryption mode %q", s) + err = fmt.Errorf("Unknown file name encryption mode %q", s) } return mode, err } @@ -580,7 +580,7 @@ func (n *nonce) pointer() *[fileNonceSize]byte { func (n *nonce) fromReader(in io.Reader) error { read, err := io.ReadFull(in, (*n)[:]) if read != fileNonceSize { - return errors.Wrap(err, "short read of nonce") + return fmt.Errorf("short read of nonce: %w", err) } return nil } @@ -956,7 +956,7 @@ func (fh *decrypter) RangeSeek(ctx context.Context, offset int64, whence int, li // Re-open the underlying object with the offset given rc, err := fh.open(ctx, underlyingOffset, underlyingLimit) if err != nil { - return 0, fh.finish(errors.Wrap(err, "couldn't reopen file with offset and limit")) + return 0, fh.finish(fmt.Errorf("couldn't reopen file with offset and limit: %w", err)) } // Set the file handle diff --git a/backend/crypt/cipher_test.go b/backend/crypt/cipher_test.go index dbe0e42be..41c37b2a8 100644 --- a/backend/crypt/cipher_test.go +++ b/backend/crypt/cipher_test.go @@ -4,13 +4,13 @@ import ( "bytes" "context" "encoding/base32" + "errors" "fmt" "io" "io/ioutil" "strings" "testing" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt/pkcs7" "github.com/rclone/rclone/lib/readers" "github.com/stretchr/testify/assert" @@ -637,7 +637,7 @@ func (r *randomSource) Read(p []byte) (n int, err error) { func (r *randomSource) Write(p []byte) (n int, err error) { for i := range p { if p[i] != r.next() { - return 0, errors.Errorf("Error in stream at %d", r.counter) + return 0, fmt.Errorf("Error in stream at %d", r.counter) } } return len(p), nil diff --git a/backend/crypt/crypt.go b/backend/crypt/crypt.go index 57f2858bd..56a3dcccd 100644 --- a/backend/crypt/crypt.go +++ b/backend/crypt/crypt.go @@ -3,13 +3,13 @@ package crypt import ( "context" + "errors" "fmt" "io" "path" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/cache" @@ -131,18 +131,18 @@ func newCipherForConfig(opt *Options) (*Cipher, error) { } password, err := obscure.Reveal(opt.Password) if err != nil { - return nil, errors.Wrap(err, "failed to decrypt password") + return nil, fmt.Errorf("failed to decrypt password: %w", err) } var salt string if opt.Password2 != "" { salt, err = obscure.Reveal(opt.Password2) if err != nil { - return nil, errors.Wrap(err, "failed to decrypt password2") + return nil, fmt.Errorf("failed to decrypt password2: %w", err) } } cipher, err := newCipher(mode, password, salt, opt.DirectoryNameEncryption) if err != nil { - return nil, errors.Wrap(err, "failed to make cipher") + return nil, fmt.Errorf("failed to make cipher: %w", err) } return cipher, nil } @@ -192,7 +192,7 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, } } if err != fs.ErrorIsFile && err != nil { - return nil, errors.Wrapf(err, "failed to make remote %q to wrap", remote) + return nil, fmt.Errorf("failed to make remote %q to wrap: %w", remote, err) } f := &Fs{ Fs: wrappedFs, @@ -300,7 +300,7 @@ func (f *Fs) encryptEntries(ctx context.Context, entries fs.DirEntries) (newEntr case fs.Directory: f.addDir(ctx, &newEntries, x) default: - return nil, errors.Errorf("Unknown object type %T", entry) + return nil, fmt.Errorf("Unknown object type %T", entry) } } return newEntries, nil @@ -406,7 +406,7 @@ func (f *Fs) put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options [ var dstHash string dstHash, err = o.Hash(ctx, ht) if err != nil { - return nil, errors.Wrap(err, "failed to read destination hash") + return nil, fmt.Errorf("failed to read destination hash: %w", err) } if srcHash != "" && dstHash != "" { if srcHash != dstHash { @@ -415,7 +415,7 @@ func (f *Fs) put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options [ if err != nil { fs.Errorf(o, "Failed to remove corrupted object: %v", err) } - return nil, errors.Errorf("corrupted on transfer: %v crypted hash differ %q vs %q", ht, srcHash, dstHash) + return nil, fmt.Errorf("corrupted on transfer: %v crypted hash differ %q vs %q", ht, srcHash, dstHash) } fs.Debugf(src, "%v = %s OK", ht, srcHash) } @@ -616,24 +616,24 @@ func (f *Fs) computeHashWithNonce(ctx context.Context, nonce nonce, src fs.Objec // Open the src for input in, err := src.Open(ctx) if err != nil { - return "", errors.Wrap(err, "failed to open src") + return "", fmt.Errorf("failed to open src: %w", err) } defer fs.CheckClose(in, &err) // Now encrypt the src with the nonce out, err := f.cipher.newEncrypter(in, &nonce) if err != nil { - return "", errors.Wrap(err, "failed to make encrypter") + return "", fmt.Errorf("failed to make encrypter: %w", err) } // pipe into hash m, err := hash.NewMultiHasherTypes(hash.NewHashSet(hashType)) if err != nil { - return "", errors.Wrap(err, "failed to make hasher") + return "", fmt.Errorf("failed to make hasher: %w", err) } _, err = io.Copy(m, out) if err != nil { - return "", errors.Wrap(err, "failed to hash data") + return "", fmt.Errorf("failed to hash data: %w", err) } return m.Sums()[hashType], nil @@ -652,12 +652,12 @@ func (f *Fs) ComputeHash(ctx context.Context, o *Object, src fs.Object, hashType // use a limited read so we only read the header in, err := o.Object.Open(ctx, &fs.RangeOption{Start: 0, End: int64(fileHeaderSize) - 1}) if err != nil { - return "", errors.Wrap(err, "failed to open object to read nonce") + return "", fmt.Errorf("failed to open object to read nonce: %w", err) } d, err := f.cipher.newDecrypter(in) if err != nil { _ = in.Close() - return "", errors.Wrap(err, "failed to open object to read nonce") + return "", fmt.Errorf("failed to open object to read nonce: %w", err) } nonce := d.nonce // fs.Debugf(o, "Read nonce % 2x", nonce) @@ -676,7 +676,7 @@ func (f *Fs) ComputeHash(ctx context.Context, o *Object, src fs.Object, hashType // Close d (and hence in) once we have read the nonce err = d.Close() if err != nil { - return "", errors.Wrap(err, "failed to close nonce read") + return "", fmt.Errorf("failed to close nonce read: %w", err) } return f.computeHashWithNonce(ctx, nonce, src, hashType) @@ -795,7 +795,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str for _, encryptedFileName := range arg { fileName, err := f.DecryptFileName(encryptedFileName) if err != nil { - return out, errors.Wrap(err, fmt.Sprintf("Failed to decrypt : %s", encryptedFileName)) + return out, fmt.Errorf("failed to decrypt: %s: %w", encryptedFileName, err) } out = append(out, fileName) } diff --git a/backend/crypt/pkcs7/pkcs7.go b/backend/crypt/pkcs7/pkcs7.go index e6d9d0fd9..db604ae4b 100644 --- a/backend/crypt/pkcs7/pkcs7.go +++ b/backend/crypt/pkcs7/pkcs7.go @@ -4,7 +4,7 @@ // buffers which are a multiple of an underlying crypto block size. package pkcs7 -import "github.com/pkg/errors" +import "errors" // Errors Unpad can return var ( diff --git a/backend/drive/drive.go b/backend/drive/drive.go old mode 100755 new mode 100644 index 5be87962b..01e3fd6a4 --- a/backend/drive/drive.go +++ b/backend/drive/drive.go @@ -11,6 +11,7 @@ import ( "bytes" "context" "crypto/tls" + "errors" "fmt" "io" "io/ioutil" @@ -25,7 +26,6 @@ import ( "text/template" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/config" @@ -188,7 +188,7 @@ func init() { opt := new(Options) err := configstruct.Set(m, opt) if err != nil { - return nil, errors.Wrap(err, "couldn't parse config into struct") + return nil, fmt.Errorf("couldn't parse config into struct: %w", err) } switch config.State { @@ -226,7 +226,7 @@ func init() { case "teamdrive_config": f, err := newFs(ctx, name, "", m) if err != nil { - return nil, errors.Wrap(err, "failed to make Fs to list Shared Drives") + return nil, fmt.Errorf("failed to make Fs to list Shared Drives: %w", err) } teamDrives, err := f.listTeamDrives(ctx) if err != nil { @@ -755,7 +755,7 @@ func (f *Fs) getFile(ctx context.Context, ID string, fields googleapi.Field) (in func (f *Fs) getRootID(ctx context.Context) (string, error) { info, err := f.getFile(ctx, "root", "id") if err != nil { - return "", errors.Wrap(err, "couldn't find root directory ID") + return "", fmt.Errorf("couldn't find root directory ID: %w", err) } return info.Id, nil } @@ -882,7 +882,7 @@ OUTER: return f.shouldRetry(ctx, err) }) if err != nil { - return false, errors.Wrap(err, "couldn't list directory") + return false, fmt.Errorf("couldn't list directory: %w", err) } if files.IncompleteSearch { fs.Errorf(f, "search result INCOMPLETE") @@ -904,7 +904,7 @@ OUTER: } item, err = f.resolveShortcut(ctx, item) if err != nil { - return false, errors.Wrap(err, "list") + return false, fmt.Errorf("list: %w", err) } } // Check the case of items is correct since @@ -965,7 +965,7 @@ func fixMimeType(mimeTypeIn string) string { mimeTypeOut = mime.FormatMediaType(mediaType, param) } if mimeTypeOut == "" { - panic(errors.Errorf("unable to fix MIME type %q", mimeTypeIn)) + panic(fmt.Errorf("unable to fix MIME type %q", mimeTypeIn)) } return mimeTypeOut } @@ -1000,7 +1000,7 @@ func parseExtensions(extensionsIn ...string) (extensions, mimeTypes []string, er } mt := mime.TypeByExtension(extension) if mt == "" { - return extensions, mimeTypes, errors.Errorf("couldn't find MIME type for extension %q", extension) + return extensions, mimeTypes, fmt.Errorf("couldn't find MIME type for extension %q", extension) } if !containsString(extensions, extension) { extensions = append(extensions, extension) @@ -1027,7 +1027,7 @@ func getServiceAccountClient(ctx context.Context, opt *Options, credentialsData scopes := driveScopes(opt.Scope) conf, err := google.JWTConfigFromJSON(credentialsData, scopes...) if err != nil { - return nil, errors.Wrap(err, "error processing credentials") + return nil, fmt.Errorf("error processing credentials: %w", err) } if opt.Impersonate != "" { conf.Subject = opt.Impersonate @@ -1044,19 +1044,19 @@ func createOAuthClient(ctx context.Context, opt *Options, name string, m configm if len(opt.ServiceAccountCredentials) == 0 && opt.ServiceAccountFile != "" { loadedCreds, err := ioutil.ReadFile(env.ShellExpand(opt.ServiceAccountFile)) if err != nil { - return nil, errors.Wrap(err, "error opening service account credentials file") + return nil, fmt.Errorf("error opening service account credentials file: %w", err) } opt.ServiceAccountCredentials = string(loadedCreds) } if opt.ServiceAccountCredentials != "" { oAuthClient, err = getServiceAccountClient(ctx, opt, []byte(opt.ServiceAccountCredentials)) if err != nil { - return nil, errors.Wrap(err, "failed to create oauth client from service account") + return nil, fmt.Errorf("failed to create oauth client from service account: %w", err) } } else { oAuthClient, _, err = oauthutil.NewClientWithBaseClient(ctx, name, m, driveConfig, getClient(ctx, opt)) if err != nil { - return nil, errors.Wrap(err, "failed to create oauth client") + return nil, fmt.Errorf("failed to create oauth client: %w", err) } } @@ -1065,10 +1065,10 @@ func createOAuthClient(ctx context.Context, opt *Options, name string, m configm func checkUploadChunkSize(cs fs.SizeSuffix) error { if !isPowerOfTwo(int64(cs)) { - return errors.Errorf("%v isn't a power of two", cs) + return fmt.Errorf("%v isn't a power of two", cs) } if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -1106,16 +1106,16 @@ func newFs(ctx context.Context, name, path string, m configmap.Mapper) (*Fs, err } err = checkUploadCutoff(opt.UploadCutoff) if err != nil { - return nil, errors.Wrap(err, "drive: upload cutoff") + return nil, fmt.Errorf("drive: upload cutoff: %w", err) } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "drive: chunk size") + return nil, fmt.Errorf("drive: chunk size: %w", err) } oAuthClient, err := createOAuthClient(ctx, opt, name, m) if err != nil { - return nil, errors.Wrap(err, "drive: failed when making oauth client") + return nil, fmt.Errorf("drive: failed when making oauth client: %w", err) } root, err := parseDrivePath(path) @@ -1149,13 +1149,13 @@ func newFs(ctx context.Context, name, path string, m configmap.Mapper) (*Fs, err f.client = oAuthClient f.svc, err = drive.New(f.client) if err != nil { - return nil, errors.Wrap(err, "couldn't create Drive client") + return nil, fmt.Errorf("couldn't create Drive client: %w", err) } if f.opt.V2DownloadMinSize >= 0 { f.v2Svc, err = drive_v2.New(f.client) if err != nil { - return nil, errors.Wrap(err, "couldn't create Drive v2 client") + return nil, fmt.Errorf("couldn't create Drive v2 client: %w", err) } } @@ -1180,7 +1180,8 @@ func NewFs(ctx context.Context, name, path string, m configmap.Mapper) (fs.Fs, e // otherwise look up the actual root ID rootID, err := f.getRootID(ctx) if err != nil { - if gerr, ok := errors.Cause(err).(*googleapi.Error); ok && gerr.Code == 404 { + var gerr *googleapi.Error + if errors.As(err, &gerr) && gerr.Code == 404 { // 404 means that this scope does not have permission to get the // root so just use "root" rootID = "root" @@ -1322,7 +1323,7 @@ func (f *Fs) newDocumentObject(remote string, info *drive.File, extension, expor func (f *Fs) newLinkObject(remote string, info *drive.File, extension, exportMimeType string) (fs.Object, error) { t := linkTemplate(exportMimeType) if t == nil { - return nil, errors.Errorf("unsupported link type %s", exportMimeType) + return nil, fmt.Errorf("unsupported link type %s", exportMimeType) } xdgIcon := _mimeTypeToXDGLinkIcons[info.MimeType] if xdgIcon == "" { @@ -1335,7 +1336,7 @@ func (f *Fs) newLinkObject(remote string, info *drive.File, extension, exportMim info.WebViewLink, info.Name, xdgIcon, }) if err != nil { - return nil, errors.Wrap(err, "executing template failed") + return nil, fmt.Errorf("executing template failed: %w", err) } baseObject := f.newBaseObject(remote+extension, info) @@ -1372,7 +1373,7 @@ func (f *Fs) newObjectWithExportInfo( // will have been resolved so this will do nothing. info, err = f.resolveShortcut(ctx, info) if err != nil { - return nil, errors.Wrap(err, "new object") + return nil, fmt.Errorf("new object: %w", err) } switch { case info.MimeType == driveFolderType: @@ -2015,13 +2016,14 @@ func (f *Fs) resolveShortcut(ctx context.Context, item *drive.File) (newItem *dr } newItem, err = f.getFile(ctx, item.ShortcutDetails.TargetId, f.fileFields) if err != nil { - if gerr, ok := errors.Cause(err).(*googleapi.Error); ok && gerr.Code == 404 { + var gerr *googleapi.Error + if errors.As(err, &gerr) && gerr.Code == 404 { // 404 means dangling shortcut, so just return the shortcut with the mime type mangled fs.Logf(nil, "Dangling shortcut %q detected", item.Name) item.MimeType = shortcutMimeTypeDangling return item, nil } - return nil, errors.Wrap(err, "failed to resolve shortcut") + return nil, fmt.Errorf("failed to resolve shortcut: %w", err) } // make sure we use the Name, Parents and Trashed from the original item newItem.Name = item.Name @@ -2123,10 +2125,10 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, exportExt, _, _ = f.findExportFormatByMimeType(ctx, importMimeType) if exportExt == "" { - return nil, errors.Errorf("No export format found for %q", importMimeType) + return nil, fmt.Errorf("No export format found for %q", importMimeType) } if exportExt != srcExt && !f.opt.AllowImportNameChange { - return nil, errors.Errorf("Can't convert %q to a document with a different export filetype (%q)", srcExt, exportExt) + return nil, fmt.Errorf("Can't convert %q to a document with a different export filetype (%q)", srcExt, exportExt) } } } @@ -2194,7 +2196,7 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { return false }) if err != nil { - return errors.Wrapf(err, "MergeDirs list failed on %v", srcDir) + return fmt.Errorf("MergeDirs list failed on %v: %w", srcDir, err) } // move them into place for _, info := range infos { @@ -2210,14 +2212,14 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { return f.shouldRetry(ctx, err) }) if err != nil { - return errors.Wrapf(err, "MergeDirs move failed on %q in %v", info.Name, srcDir) + return fmt.Errorf("MergeDirs move failed on %q in %v: %w", info.Name, srcDir, err) } } // rmdir (into trash) the now empty source directory fs.Infof(srcDir, "removing empty directory") err = f.delete(ctx, srcDir.ID(), true) if err != nil { - return errors.Wrapf(err, "MergeDirs move failed to rmdir %q", srcDir) + return fmt.Errorf("MergeDirs move failed to rmdir %q: %w", srcDir, err) } } return nil @@ -2280,7 +2282,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return err } if found { - return errors.Errorf("directory not empty") + return fmt.Errorf("directory not empty") } } if root != "" { @@ -2458,7 +2460,7 @@ func (f *Fs) cleanupTeamDrive(ctx context.Context, dir string, directoryID strin return false }) if err != nil { - err = errors.Wrap(err, "failed to list directory") + err = fmt.Errorf("failed to list directory: %w", err) r.Errors++ fs.Errorf(dir, "%v", err) } @@ -2502,7 +2504,7 @@ func (f *Fs) teamDriveOK(ctx context.Context) (err error) { return f.shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "failed to get Shared Drive info") + return fmt.Errorf("failed to get Shared Drive info: %w", err) } fs.Debugf(f, "read info from Shared Drive %q", td.Name) return err @@ -2525,7 +2527,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { return f.shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get Drive storageQuota") + return nil, fmt.Errorf("failed to get Drive storageQuota: %w", err) } q := about.StorageQuota usage := &fs.Usage{ @@ -2849,7 +2851,7 @@ func (f *Fs) Hashes() hash.Set { func (f *Fs) changeChunkSize(chunkSizeString string) (err error) { chunkSizeInt, err := strconv.ParseInt(chunkSizeString, 10, 64) if err != nil { - return errors.Wrap(err, "couldn't convert chunk size to int") + return fmt.Errorf("couldn't convert chunk size to int: %w", err) } chunkSize := fs.SizeSuffix(chunkSizeInt) if chunkSize == f.opt.ChunkSize { @@ -2886,17 +2888,17 @@ func (f *Fs) changeServiceAccountFile(ctx context.Context, file string) (err err f.opt.ServiceAccountCredentials = "" oAuthClient, err := createOAuthClient(ctx, &f.opt, f.name, f.m) if err != nil { - return errors.Wrap(err, "drive: failed when making oauth client") + return fmt.Errorf("drive: failed when making oauth client: %w", err) } f.client = oAuthClient f.svc, err = drive.New(f.client) if err != nil { - return errors.Wrap(err, "couldn't create Drive client") + return fmt.Errorf("couldn't create Drive client: %w", err) } if f.opt.V2DownloadMinSize >= 0 { f.v2Svc, err = drive_v2.New(f.client) if err != nil { - return errors.Wrap(err, "couldn't create Drive v2 client") + return fmt.Errorf("couldn't create Drive v2 client: %w", err) } } return nil @@ -2925,12 +2927,12 @@ func (f *Fs) makeShortcut(ctx context.Context, srcPath string, dstFs *Fs, dstPat isDir = true } else if srcObj, err := srcFs.NewObject(ctx, srcPath); err != nil { if err != fs.ErrorIsDir { - return nil, errors.Wrap(err, "can't find source") + return nil, fmt.Errorf("can't find source: %w", err) } // source was a directory srcID, err = srcFs.dirCache.FindDir(ctx, srcPath, false) if err != nil { - return nil, errors.Wrap(err, "failed to find source dir") + return nil, fmt.Errorf("failed to find source dir: %w", err) } isDir = true } else { @@ -2947,13 +2949,13 @@ func (f *Fs) makeShortcut(ctx context.Context, srcPath string, dstFs *Fs, dstPat } else if err == fs.ErrorIsDir { err = errors.New("existing directory") } - return nil, errors.Wrap(err, "not overwriting shortcut target") + return nil, fmt.Errorf("not overwriting shortcut target: %w", err) } // Create destination shortcut createInfo, err := dstFs.createFileInfo(ctx, dstPath, time.Now()) if err != nil { - return nil, errors.Wrap(err, "shortcut destination failed") + return nil, fmt.Errorf("shortcut destination failed: %w", err) } createInfo.MimeType = shortcutMimeType createInfo.ShortcutDetails = &drive.FileShortcutDetails{ @@ -2970,7 +2972,7 @@ func (f *Fs) makeShortcut(ctx context.Context, srcPath string, dstFs *Fs, dstPat return dstFs.shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "shortcut creation failed") + return nil, fmt.Errorf("shortcut creation failed: %w", err) } if isDir { return nil, nil @@ -2990,7 +2992,7 @@ func (f *Fs) listTeamDrives(ctx context.Context) (drives []*drive.Drive, err err return defaultFs.shouldRetry(ctx, err) }) if err != nil { - return drives, errors.Wrap(err, "listing Team Drives failed") + return drives, fmt.Errorf("listing Team Drives failed: %w", err) } drives = append(drives, teamDrives.Drives...) if teamDrives.NextPageToken == "" { @@ -3033,7 +3035,7 @@ func (f *Fs) unTrash(ctx context.Context, dir string, directoryID string, recurs return f.shouldRetry(ctx, err) }) if err != nil { - err = errors.Wrap(err, "failed to restore") + err = fmt.Errorf("failed to restore: %w", err) r.Errors++ fs.Errorf(remote, "%v", err) } else { @@ -3050,7 +3052,7 @@ func (f *Fs) unTrash(ctx context.Context, dir string, directoryID string, recurs return false }) if err != nil { - err = errors.Wrap(err, "failed to list directory") + err = fmt.Errorf("failed to list directory: %w", err) r.Errors++ fs.Errorf(dir, "%v", err) } @@ -3074,10 +3076,10 @@ func (f *Fs) unTrashDir(ctx context.Context, dir string, recurse bool) (r unTras func (f *Fs) copyID(ctx context.Context, id, dest string) (err error) { info, err := f.getFile(ctx, id, f.fileFields) if err != nil { - return errors.Wrap(err, "couldn't find id") + return fmt.Errorf("couldn't find id: %w", err) } if info.MimeType == driveFolderType { - return errors.Errorf("can't copy directory use: rclone copy --drive-root-folder-id %s %s %s", id, fs.ConfigString(f), dest) + return fmt.Errorf("can't copy directory use: rclone copy --drive-root-folder-id %s %s %s", id, fs.ConfigString(f), dest) } info.Name = f.opt.Enc.ToStandardName(info.Name) o, err := f.newObjectWithInfo(ctx, info.Name, info) @@ -3100,7 +3102,7 @@ func (f *Fs) copyID(ctx context.Context, id, dest string) (err error) { } _, err = operations.Copy(ctx, dstFs, nil, destLeaf, o) if err != nil { - return errors.Wrap(err, "copy failed") + return fmt.Errorf("copy failed: %w", err) } return nil } @@ -3299,7 +3301,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str if ok { targetFs, err := cache.Get(ctx, target) if err != nil { - return nil, errors.Wrap(err, "couldn't find target") + return nil, fmt.Errorf("couldn't find target: %w", err) } dstFs, ok = targetFs.(*Fs) if !ok { @@ -3338,7 +3340,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str arg = arg[2:] err = f.copyID(ctx, id, dest) if err != nil { - return nil, errors.Wrapf(err, "failed copying %q to %q", id, dest) + return nil, fmt.Errorf("failed copying %q to %q: %w", id, dest, err) } } return nil, nil @@ -3572,11 +3574,11 @@ func (o *baseObject) open(ctx context.Context, url string, options ...fs.OpenOpt url += "acknowledgeAbuse=true" _, res, err = o.httpResponse(ctx, url, "GET", options) } else { - err = errors.Wrap(err, "Use the --drive-acknowledge-abuse flag to download this file") + err = fmt.Errorf("Use the --drive-acknowledge-abuse flag to download this file: %w", err) } } if err != nil { - return nil, errors.Wrap(err, "open file failed") + return nil, fmt.Errorf("open file failed: %w", err) } } return res.Body, nil @@ -3740,14 +3742,14 @@ func (o *documentObject) Update(ctx context.Context, in io.Reader, src fs.Object } if o.fs.importMimeTypes == nil || o.fs.opt.SkipGdocs { - return errors.Errorf("can't update google document type without --drive-import-formats") + return fmt.Errorf("can't update google document type without --drive-import-formats") } importMimeType = o.fs.findImportFormat(ctx, updateInfo.MimeType) if importMimeType == "" { - return errors.Errorf("no import format found for %q", srcMimeType) + return fmt.Errorf("no import format found for %q", srcMimeType) } if importMimeType != o.documentMimeType { - return errors.Errorf("can't change google document type (o: %q, src: %q, import: %q)", o.documentMimeType, srcMimeType, importMimeType) + return fmt.Errorf("can't change google document type (o: %q, src: %q, import: %q)", o.documentMimeType, srcMimeType, importMimeType) } updateInfo.MimeType = importMimeType diff --git a/backend/drive/drive_internal_test.go b/backend/drive/drive_internal_test.go index 2f108eb89..cd06d15cd 100644 --- a/backend/drive/drive_internal_test.go +++ b/backend/drive/drive_internal_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -15,7 +16,6 @@ import ( "testing" "time" - "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/local" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/filter" diff --git a/backend/dropbox/batcher.go b/backend/dropbox/batcher.go index 098f0840c..96185dde3 100644 --- a/backend/dropbox/batcher.go +++ b/backend/dropbox/batcher.go @@ -8,13 +8,13 @@ package dropbox import ( "context" + "errors" "fmt" "sync" "time" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/async" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/files" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/lib/atexit" @@ -66,7 +66,7 @@ type batcherResponse struct { func newBatcher(ctx context.Context, f *Fs, mode string, size int, timeout time.Duration) (*batcher, error) { // fs.Debugf(f, "Creating batcher with mode %q, size %d, timeout %v", mode, size, timeout) if size > maxBatchSize || size < 0 { - return nil, errors.Errorf("dropbox: batch size must be < %d and >= 0 - it is currently %d", maxBatchSize, size) + return nil, fmt.Errorf("dropbox: batch size must be < %d and >= 0 - it is currently %d", maxBatchSize, size) } async := false @@ -91,7 +91,7 @@ func newBatcher(ctx context.Context, f *Fs, mode string, size int, timeout time. case "off": size = 0 default: - return nil, errors.Errorf("dropbox: batch mode must be sync|async|off not %q", mode) + return nil, fmt.Errorf("dropbox: batch mode must be sync|async|off not %q", mode) } b := &batcher{ @@ -135,7 +135,7 @@ func (b *batcher) finishBatch(ctx context.Context, items []*files.UploadSessionF return err != nil, err }) if err != nil { - return nil, errors.Wrap(err, "batch commit failed") + return nil, fmt.Errorf("batch commit failed: %w", err) } return batchStatus, nil } @@ -180,7 +180,7 @@ func (b *batcher) finishBatchJobStatus(ctx context.Context, launchBatchStatus *f if err == nil { err = errors.New("batch didn't complete") } - return nil, errors.Wrapf(err, "wait for batch failed after %d tries in %v", try, time.Since(startTime)) + return nil, fmt.Errorf("wait for batch failed after %d tries in %v: %w", try, time.Since(startTime), err) } // commit a batch @@ -216,13 +216,13 @@ func (b *batcher) commitBatch(ctx context.Context, items []*files.UploadSessionF case "complete": complete = batchStatus.Complete default: - return errors.Errorf("batch returned unknown status %q", batchStatus.Tag) + return fmt.Errorf("batch returned unknown status %q", batchStatus.Tag) } // Check we got the right number of entries entries := complete.Entries if len(entries) != len(results) { - return errors.Errorf("expecting %d items in batch but got %d", len(results), len(entries)) + return fmt.Errorf("expecting %d items in batch but got %d", len(results), len(entries)) } // Report results to clients @@ -250,7 +250,7 @@ func (b *batcher) commitBatch(ctx context.Context, items []*files.UploadSessionF errorTag += "/" + item.Failure.PropertiesError.Tag } } - resp.err = errors.Errorf("batch upload failed: %s", errorTag) + resp.err = fmt.Errorf("batch upload failed: %s", errorTag) } if !b.async { results[i] <- resp @@ -261,7 +261,7 @@ func (b *batcher) commitBatch(ctx context.Context, items []*files.UploadSessionF // Report an error if any failed in the batch if errorTag != "" { - return errors.Errorf("batch had %d errors: last error: %s", errorCount, errorTag) + return fmt.Errorf("batch had %d errors: last error: %s", errorCount, errorTag) } fs.Debugf(b.f, "Committed %s", desc) diff --git a/backend/dropbox/dropbox.go b/backend/dropbox/dropbox.go old mode 100755 new mode 100644 index b8c69a3be..11436a327 --- a/backend/dropbox/dropbox.go +++ b/backend/dropbox/dropbox.go @@ -23,6 +23,7 @@ of path_display and all will be well. import ( "context" + "errors" "fmt" "io" "path" @@ -38,7 +39,6 @@ import ( "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/sharing" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/team" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox/users" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/dropbox/dbhash" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -363,24 +363,24 @@ func shouldRetry(ctx context.Context, err error) (bool, error) { if err == nil { return false, err } - baseErrString := errors.Cause(err).Error() + errString := err.Error() // First check for specific errors - if strings.Contains(baseErrString, "insufficient_space") { + if strings.Contains(errString, "insufficient_space") { return false, fserrors.FatalError(err) - } else if strings.Contains(baseErrString, "malformed_path") { + } else if strings.Contains(errString, "malformed_path") { return false, fserrors.NoRetryError(err) } // Then handle any official Retry-After header from Dropbox's SDK switch e := err.(type) { case auth.RateLimitAPIError: if e.RateLimitError.RetryAfter > 0 { - fs.Logf(baseErrString, "Too many requests or write operations. Trying again in %d seconds.", e.RateLimitError.RetryAfter) + fs.Logf(errString, "Too many requests or write operations. Trying again in %d seconds.", e.RateLimitError.RetryAfter) err = pacer.RetryAfterError(err, time.Duration(e.RateLimitError.RetryAfter)*time.Second) } return true, err } // Keep old behavior for backward compatibility - if strings.Contains(baseErrString, "too_many_write_operations") || strings.Contains(baseErrString, "too_many_requests") || baseErrString == "" { + if strings.Contains(errString, "too_many_write_operations") || strings.Contains(errString, "too_many_requests") || errString == "" { return true, err } return fserrors.ShouldRetry(err), err @@ -389,10 +389,10 @@ func shouldRetry(ctx context.Context, err error) (bool, error) { func checkUploadChunkSize(cs fs.SizeSuffix) error { const minChunkSize = fs.SizeSuffixBase if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } if cs > maxChunkSize { - return errors.Errorf("%s is greater than %s", cs, maxChunkSize) + return fmt.Errorf("%s is greater than %s", cs, maxChunkSize) } return nil } @@ -415,7 +415,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "dropbox: chunk size") + return nil, fmt.Errorf("dropbox: chunk size: %w", err) } // Convert the old token if it exists. The old token was just @@ -427,13 +427,13 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e newToken := fmt.Sprintf(`{"access_token":"%s","token_type":"bearer","expiry":"0001-01-01T00:00:00Z"}`, oldToken) err := config.SetValueAndSave(name, config.ConfigToken, newToken) if err != nil { - return nil, errors.Wrap(err, "NewFS convert token") + return nil, fmt.Errorf("NewFS convert token: %w", err) } } oAuthClient, _, err := oauthutil.NewClient(ctx, name, m, getOauthConfig(m)) if err != nil { - return nil, errors.Wrap(err, "failed to configure dropbox") + return nil, fmt.Errorf("failed to configure dropbox: %w", err) } ci := fs.GetConfig(ctx) @@ -474,7 +474,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e memberIds, err := f.team.MembersGetInfo(args) if err != nil { - return nil, errors.Wrapf(err, "invalid dropbox team member: %q", opt.Impersonate) + return nil, fmt.Errorf("invalid dropbox team member: %q: %w", opt.Impersonate, err) } cfg.AsMemberID = memberIds[0].MemberInfo.Profile.MemberProfile.TeamMemberId @@ -551,7 +551,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "get current account failed") + return nil, fmt.Errorf("get current account failed: %w", err) } switch x := acc.RootInfo.(type) { case *common.TeamRootInfo: @@ -559,7 +559,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e case *common.UserRootInfo: f.ns = x.RootNamespaceId default: - return nil, errors.Errorf("unknown RootInfo type %v %T", acc.RootInfo, acc.RootInfo) + return nil, fmt.Errorf("unknown RootInfo type %v %T", acc.RootInfo, acc.RootInfo) } fs.Debugf(f, "Using root namespace %q", f.ns) } @@ -710,7 +710,7 @@ func (f *Fs) listSharedFolders(ctx context.Context) (entries fs.DirEntries, err return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "list continue") + return nil, fmt.Errorf("list continue: %w", err) } } for _, entry := range res.Entries { @@ -784,7 +784,7 @@ func (f *Fs) listReceivedFiles(ctx context.Context) (entries fs.DirEntries, err return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "list continue") + return nil, fmt.Errorf("list continue: %w", err) } } for _, entry := range res.Entries { @@ -877,7 +877,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "list continue") + return nil, fmt.Errorf("list continue: %w", err) } } for _, entry := range res.Entries { @@ -989,7 +989,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) (err error) // check directory exists _, err = f.getDirMetadata(ctx, root) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } root = f.opt.Enc.FromStandardPath(root) @@ -1007,7 +1007,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) (err error) return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } if len(res.Entries) != 0 { return errors.New("directory not empty") @@ -1073,7 +1073,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "copy failed") + return nil, fmt.Errorf("copy failed: %w", err) } // Set the metadata @@ -1083,7 +1083,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, } err = dstObj.setMetadataFromEntry(fileInfo) if err != nil { - return nil, errors.Wrap(err, "copy failed") + return nil, fmt.Errorf("copy failed: %w", err) } return dstObj, nil @@ -1134,7 +1134,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "move failed") + return nil, fmt.Errorf("move failed: %w", err) } // Set the metadata @@ -1144,7 +1144,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } err = dstObj.setMetadataFromEntry(fileInfo) if err != nil { - return nil, errors.Wrap(err, "move failed") + return nil, fmt.Errorf("move failed: %w", err) } return dstObj, nil } @@ -1252,7 +1252,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "MoveDir failed") + return fmt.Errorf("MoveDir failed: %w", err) } return nil @@ -1266,7 +1266,7 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "about failed") + return nil, fmt.Errorf("about failed: %w", err) } var total uint64 if q.Allocation != nil { @@ -1406,7 +1406,7 @@ func (f *Fs) changeNotifyRunner(ctx context.Context, notifyFunc func(string, fs. return shouldRetry(ctx, err) }) if err != nil { - return "", errors.Wrap(err, "list continue") + return "", fmt.Errorf("list continue: %w", err) } cursor = changeList.Cursor var entryType fs.EntryType @@ -1485,7 +1485,7 @@ func (o *Object) Hash(ctx context.Context, t hash.Type) (string, error) { } err := o.readMetaData(ctx) if err != nil { - return "", errors.Wrap(err, "failed to read hash from metadata") + return "", fmt.Errorf("failed to read hash from metadata: %w", err) } return o.hash, nil } @@ -1738,7 +1738,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } remote := o.remotePath() if ignoredFiles.MatchString(remote) { - return fserrors.NoRetryError(errors.Errorf("file name %q is disallowed - not uploading", path.Base(remote))) + return fserrors.NoRetryError(fmt.Errorf("file name %q is disallowed - not uploading", path.Base(remote))) } commitInfo := files.NewCommitInfo(o.fs.opt.Enc.FromStandardPath(o.remotePath())) commitInfo.Mode.Tag = "overwrite" @@ -1762,7 +1762,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op }) } if err != nil { - return errors.Wrap(err, "upload failed") + return fmt.Errorf("upload failed: %w", err) } // If we haven't received data back from batch upload then fake it // diff --git a/backend/fichier/api.go b/backend/fichier/api.go index 54d4b2cd5..6a1746265 100644 --- a/backend/fichier/api.go +++ b/backend/fichier/api.go @@ -2,6 +2,8 @@ package fichier import ( "context" + "errors" + "fmt" "io" "net/http" "net/url" @@ -10,7 +12,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/lib/rest" @@ -81,7 +82,7 @@ func (f *Fs) readFileInfo(ctx context.Context, url string) (*File, error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't read file info") + return nil, fmt.Errorf("couldn't read file info: %w", err) } return &file, err @@ -110,7 +111,7 @@ func (f *Fs) getDownloadToken(ctx context.Context, url string) (*GetTokenRespons return doretry || !validToken(&token), err }) if err != nil { - return nil, errors.Wrap(err, "couldn't list files") + return nil, fmt.Errorf("couldn't list files: %w", err) } return &token, nil @@ -144,7 +145,7 @@ func (f *Fs) listSharedFiles(ctx context.Context, id string) (entries fs.DirEntr return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't list files") + return nil, fmt.Errorf("couldn't list files: %w", err) } entries = make([]fs.DirEntry, len(sharedFiles)) @@ -173,7 +174,7 @@ func (f *Fs) listFiles(ctx context.Context, directoryID int) (filesList *FilesLi return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't list files") + return nil, fmt.Errorf("couldn't list files: %w", err) } for i := range filesList.Items { item := &filesList.Items[i] @@ -201,7 +202,7 @@ func (f *Fs) listFolders(ctx context.Context, directoryID int) (foldersList *Fol return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't list folders") + return nil, fmt.Errorf("couldn't list folders: %w", err) } foldersList.Name = f.opt.Enc.ToStandardName(foldersList.Name) for i := range foldersList.SubFolders { @@ -295,7 +296,7 @@ func (f *Fs) makeFolder(ctx context.Context, leaf string, folderID int) (respons return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't create folder") + return nil, fmt.Errorf("couldn't create folder: %w", err) } // fs.Debugf(f, "Created Folder `%s` in id `%s`", name, directoryID) @@ -322,10 +323,10 @@ func (f *Fs) removeFolder(ctx context.Context, name string, folderID int) (respo return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't remove folder") + return nil, fmt.Errorf("couldn't remove folder: %w", err) } if response.Status != "OK" { - return nil, errors.Errorf("can't remove folder: %s", response.Message) + return nil, fmt.Errorf("can't remove folder: %s", response.Message) } // fs.Debugf(f, "Removed Folder with id `%s`", directoryID) @@ -352,7 +353,7 @@ func (f *Fs) deleteFile(ctx context.Context, url string) (response *GenericOKRes }) if err != nil { - return nil, errors.Wrap(err, "couldn't remove file") + return nil, fmt.Errorf("couldn't remove file: %w", err) } // fs.Debugf(f, "Removed file with url `%s`", url) @@ -379,7 +380,7 @@ func (f *Fs) moveFile(ctx context.Context, url string, folderID int, rename stri }) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } return response, nil @@ -404,7 +405,7 @@ func (f *Fs) copyFile(ctx context.Context, url string, folderID int, rename stri }) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } return response, nil @@ -432,7 +433,7 @@ func (f *Fs) renameFile(ctx context.Context, url string, newName string) (respon }) if err != nil { - return nil, errors.Wrap(err, "couldn't rename file") + return nil, fmt.Errorf("couldn't rename file: %w", err) } return response, nil @@ -453,7 +454,7 @@ func (f *Fs) getUploadNode(ctx context.Context) (response *GetUploadNodeResponse return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "didnt got an upload node") + return nil, fmt.Errorf("didnt got an upload node: %w", err) } // fs.Debugf(f, "Got Upload node") @@ -497,7 +498,7 @@ func (f *Fs) uploadFile(ctx context.Context, in io.Reader, size int64, fileName, }) if err != nil { - return nil, errors.Wrap(err, "couldn't upload file") + return nil, fmt.Errorf("couldn't upload file: %w", err) } // fs.Debugf(f, "Uploaded File `%s`", fileName) @@ -531,7 +532,7 @@ func (f *Fs) endUpload(ctx context.Context, uploadID string, nodeurl string) (re }) if err != nil { - return nil, errors.Wrap(err, "couldn't finish file upload") + return nil, fmt.Errorf("couldn't finish file upload: %w", err) } return response, err diff --git a/backend/fichier/fichier.go b/backend/fichier/fichier.go index 92a41432c..b20f2ed31 100644 --- a/backend/fichier/fichier.go +++ b/backend/fichier/fichier.go @@ -2,6 +2,7 @@ package fichier import ( "context" + "errors" "fmt" "io" "net/http" @@ -9,7 +10,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -454,10 +454,10 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, if currentDirectoryID == directoryID { resp, err := f.renameFile(ctx, srcObj.file.URL, leaf) if err != nil { - return nil, errors.Wrap(err, "couldn't rename file") + return nil, fmt.Errorf("couldn't rename file: %w", err) } if resp.Status != "OK" { - return nil, errors.Errorf("couldn't rename file: %s", resp.Message) + return nil, fmt.Errorf("couldn't rename file: %s", resp.Message) } url = resp.URLs[0].URL } else { @@ -467,10 +467,10 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } resp, err := f.moveFile(ctx, srcObj.file.URL, folderID, leaf) if err != nil { - return nil, errors.Wrap(err, "couldn't move file") + return nil, fmt.Errorf("couldn't move file: %w", err) } if resp.Status != "OK" { - return nil, errors.Errorf("couldn't move file: %s", resp.Message) + return nil, fmt.Errorf("couldn't move file: %s", resp.Message) } url = resp.URLs[0] } @@ -503,10 +503,10 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, } resp, err := f.copyFile(ctx, srcObj.file.URL, folderID, leaf) if err != nil { - return nil, errors.Wrap(err, "couldn't move file") + return nil, fmt.Errorf("couldn't move file: %w", err) } if resp.Status != "OK" { - return nil, errors.Errorf("couldn't move file: %s", resp.Message) + return nil, fmt.Errorf("couldn't move file: %s", resp.Message) } file, err := f.readFileInfo(ctx, resp.URLs[0].ToURL) diff --git a/backend/fichier/object.go b/backend/fichier/object.go index d48047035..73723e223 100644 --- a/backend/fichier/object.go +++ b/backend/fichier/object.go @@ -2,11 +2,12 @@ package fichier import ( "context" + "errors" + "fmt" "io" "net/http" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/lib/rest" @@ -122,7 +123,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // Delete duplicate after successful upload err = o.Remove(ctx) if err != nil { - return errors.Wrap(err, "failed to remove old version") + return fmt.Errorf("failed to remove old version: %w", err) } // Replace guts of old object with new one diff --git a/backend/filefabric/filefabric.go b/backend/filefabric/filefabric.go index 61a303a23..7f49579b4 100644 --- a/backend/filefabric/filefabric.go +++ b/backend/filefabric/filefabric.go @@ -17,6 +17,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "io" "io/ioutil" @@ -32,7 +33,6 @@ import ( "github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/random" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/filefabric/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -267,7 +267,7 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, rootID string, path string "pid": rootID, }, &resp, nil) if err != nil { - return nil, errors.Wrap(err, "failed to check path exists") + return nil, fmt.Errorf("failed to check path exists: %w", err) } if resp.Exists != "y" { return nil, fs.ErrorObjectNotFound @@ -308,7 +308,7 @@ func (f *Fs) getApplianceInfo(ctx context.Context) error { "token": "*", }, &applianceInfo, nil) if err != nil { - return errors.Wrap(err, "failed to read appliance version") + return fmt.Errorf("failed to read appliance version: %w", err) } f.opt.Version = applianceInfo.SoftwareVersionLabel f.m.Set("version", f.opt.Version) @@ -349,7 +349,7 @@ func (f *Fs) getToken(ctx context.Context) (token string, err error) { "authtoken": f.opt.PermanentToken, }, &info, nil) if err != nil { - return "", errors.Wrap(err, "failed to get session token") + return "", fmt.Errorf("failed to get session token: %w", err) } refreshed = true now = now.Add(tokenLifeTime) @@ -562,7 +562,7 @@ func (f *Fs) CreateDir(ctx context.Context, pathID, leaf string) (newID string, "fi_name": f.opt.Enc.FromStandardName(leaf), }, &info, nil) if err != nil { - return "", errors.Wrap(err, "failed to create directory") + return "", fmt.Errorf("failed to create directory: %w", err) } // fmt.Printf("...Id %q\n", *info.Id) return info.Item.ID, nil @@ -595,7 +595,7 @@ OUTER: var info api.GetFolderContentsResponse _, err = f.rpc(ctx, "getFolderContents", p, &info, nil) if err != nil { - return false, errors.Wrap(err, "failed to list directory") + return false, fmt.Errorf("failed to list directory: %w", err) } for i := range info.Items { item := &info.Items[i] @@ -726,7 +726,7 @@ func (f *Fs) deleteObject(ctx context.Context, id string) (err error) { "completedeletion": "n", }, &info, nil) if err != nil { - return errors.Wrap(err, "failed to delete file") + return fmt.Errorf("failed to delete file: %w", err) } return nil } @@ -763,7 +763,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { }, &info, nil) f.dirCache.FlushDir(dir) if err != nil { - return errors.Wrap(err, "failed to remove directory") + return fmt.Errorf("failed to remove directory: %w", err) } return nil } @@ -825,7 +825,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, } _, err = f.rpc(ctx, "doCopyFile", p, &info, nil) if err != nil { - return nil, errors.Wrap(err, "failed to copy file") + return nil, fmt.Errorf("failed to copy file: %w", err) } err = dstObj.setMetaData(&info.Item) if err != nil { @@ -857,7 +857,7 @@ func (f *Fs) waitForBackgroundTask(ctx context.Context, taskID api.String) (err "taskid": taskID, }, &info, nil) if err != nil { - return errors.Wrapf(err, "failed to wait for task %s to complete", taskID) + return fmt.Errorf("failed to wait for task %s to complete: %w", taskID, err) } if len(info.Tasks) == 0 { // task has finished @@ -890,7 +890,7 @@ func (f *Fs) renameLeaf(ctx context.Context, isDir bool, id string, newLeaf stri "fi_name": newLeaf, }, &info, nil) if err != nil { - return nil, errors.Wrap(err, "failed to rename leaf") + return nil, fmt.Errorf("failed to rename leaf: %w", err) } err = f.waitForBackgroundTask(ctx, info.Status.TaskID) if err != nil { @@ -934,7 +934,7 @@ func (f *Fs) move(ctx context.Context, isDir bool, id, oldLeaf, newLeaf, oldDire "dir_id": newDirectoryID, }, &info, nil) if err != nil { - return nil, errors.Wrap(err, "failed to move file to new directory") + return nil, fmt.Errorf("failed to move file to new directory: %w", err) } item = &info.Item err = f.waitForBackgroundTask(ctx, info.Status.TaskID) @@ -1037,7 +1037,7 @@ func (f *Fs) CleanUp(ctx context.Context) (err error) { var info api.EmptyResponse _, err = f.rpc(ctx, "emptyTrashInBackground", params{}, &info, nil) if err != nil { - return errors.Wrap(err, "failed to empty trash") + return fmt.Errorf("failed to empty trash: %w", err) } return nil } @@ -1164,7 +1164,7 @@ func (o *Object) modifyFile(ctx context.Context, keyValues [][2]string) error { "data": data.String(), }, &info, nil) if err != nil { - return errors.Wrap(err, "failed to update metadata") + return fmt.Errorf("failed to update metadata: %w", err) } return o.setMetaData(&info.Item) } @@ -1247,7 +1247,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } _, err = o.fs.rpc(ctx, "doInitUpload", p, &upload, nil) if err != nil { - return errors.Wrap(err, "failed to initialize upload") + return fmt.Errorf("failed to initialize upload: %w", err) } // Cancel the upload if aborted or it fails @@ -1290,13 +1290,13 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return o.fs.shouldRetry(ctx, resp, err, nil, try) }) if err != nil { - return errors.Wrap(err, "failed to upload") + return fmt.Errorf("failed to upload: %w", err) } if uploader.Success != "y" { - return errors.Errorf("upload failed") + return fmt.Errorf("upload failed") } if size > 0 && uploader.FileSize != size { - return errors.Errorf("upload failed: size mismatch: want %d got %d", size, uploader.FileSize) + return fmt.Errorf("upload failed: size mismatch: want %d got %d", size, uploader.FileSize) } // Now finalize the file @@ -1308,7 +1308,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } _, err = o.fs.rpc(ctx, "doCompleteUpload", p, &finalize, nil) if err != nil { - return errors.Wrap(err, "failed to finalize upload") + return fmt.Errorf("failed to finalize upload: %w", err) } finalized = true diff --git a/backend/ftp/ftp.go b/backend/ftp/ftp.go index b5de006e5..11ae2764d 100644 --- a/backend/ftp/ftp.go +++ b/backend/ftp/ftp.go @@ -4,6 +4,8 @@ package ftp import ( "context" "crypto/tls" + "errors" + "fmt" "io" "net" "net/textproto" @@ -14,7 +16,6 @@ import ( "time" "github.com/jlaffaye/ftp" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/config" @@ -349,7 +350,7 @@ func (f *Fs) ftpConnection(ctx context.Context) (c *ftp.ServerConn, err error) { return false, nil }) if err != nil { - err = errors.Wrapf(err, "failed to make FTP connection to %q", f.dialAddr) + err = fmt.Errorf("failed to make FTP connection to %q: %w", f.dialAddr, err) } return c, err } @@ -396,8 +397,8 @@ func (f *Fs) putFtpConnection(pc **ftp.ServerConn, err error) { *pc = nil if err != nil { // If not a regular FTP error code then check the connection - _, isRegularError := errors.Cause(err).(*textproto.Error) - if !isRegularError { + var tpErr *textproto.Error + if !errors.As(err, &tpErr) { nopErr := c.NoOp() if nopErr != nil { fs.Debugf(f, "Connection failed, closing: %v", nopErr) @@ -445,7 +446,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs } pass, err := obscure.Reveal(opt.Pass) if err != nil { - return nil, errors.Wrap(err, "NewFS decrypt password") + return nil, fmt.Errorf("NewFS decrypt password: %w", err) } user := opt.User if user == "" { @@ -502,7 +503,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs // Make a connection and pool it to return errors early c, err := f.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "NewFs") + return nil, fmt.Errorf("NewFs: %w", err) } f.fGetTime = c.IsGetTimeSupported() f.fSetTime = c.IsSetTimeSupported() @@ -520,7 +521,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs } _, err := f.NewObject(ctx, remote) if err != nil { - if err == fs.ErrorObjectNotFound || errors.Cause(err) == fs.ErrorNotAFile { + if err == fs.ErrorObjectNotFound || errors.Is(err, fs.ErrorNotAFile) { // File doesn't exist so return old f f.root = root return f, nil @@ -599,7 +600,7 @@ func (f *Fs) findItem(ctx context.Context, remote string) (entry *ftp.Entry, err c, err := f.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "findItem") + return nil, fmt.Errorf("findItem: %w", err) } files, err := c.List(f.dirFromStandardPath(dir)) f.putFtpConnection(&c, err) @@ -643,7 +644,7 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (o fs.Object, err err func (f *Fs) dirExists(ctx context.Context, remote string) (exists bool, err error) { entry, err := f.findItem(ctx, remote) if err != nil { - return false, errors.Wrap(err, "dirExists") + return false, fmt.Errorf("dirExists: %w", err) } if entry != nil && entry.Type == ftp.EntryTypeFolder { return true, nil @@ -664,7 +665,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // defer log.Trace(dir, "dir=%q", dir)("entries=%v, err=%v", &entries, &err) c, err := f.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "list") + return nil, fmt.Errorf("list: %w", err) } var listErr error @@ -702,7 +703,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e if len(files) == 0 { exists, err := f.dirExists(ctx, dir) if err != nil { - return nil, errors.Wrap(err, "list") + return nil, fmt.Errorf("list: %w", err) } if !exists { return nil, fs.ErrorDirNotFound @@ -766,7 +767,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . // fs.Debugf(f, "Trying to put file %s", src.Remote()) err := f.mkParentDir(ctx, src.Remote()) if err != nil { - return nil, errors.Wrap(err, "Put mkParentDir failed") + return nil, fmt.Errorf("Put mkParentDir failed: %w", err) } o := &Object{ fs: f, @@ -789,7 +790,7 @@ func (f *Fs) getInfo(ctx context.Context, remote string) (fi *FileInfo, err erro c, err := f.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "getInfo") + return nil, fmt.Errorf("getInfo: %w", err) } files, err := c.List(f.dirFromStandardPath(dir)) f.putFtpConnection(&c, err) @@ -827,7 +828,7 @@ func (f *Fs) mkdir(ctx context.Context, abspath string) error { } return fs.ErrorIsFile } else if err != fs.ErrorObjectNotFound { - return errors.Wrapf(err, "mkdir %q failed", abspath) + return fmt.Errorf("mkdir %q failed: %w", abspath, err) } parent := path.Dir(abspath) err = f.mkdir(ctx, parent) @@ -836,7 +837,7 @@ func (f *Fs) mkdir(ctx context.Context, abspath string) error { } c, connErr := f.getFtpConnection(ctx) if connErr != nil { - return errors.Wrap(connErr, "mkdir") + return fmt.Errorf("mkdir: %w", connErr) } err = c.MakeDir(f.dirFromStandardPath(abspath)) f.putFtpConnection(&c, err) @@ -872,7 +873,7 @@ func (f *Fs) Mkdir(ctx context.Context, dir string) (err error) { func (f *Fs) Rmdir(ctx context.Context, dir string) error { c, err := f.getFtpConnection(ctx) if err != nil { - return errors.Wrap(translateErrorFile(err), "Rmdir") + return fmt.Errorf("Rmdir: %w", translateErrorFile(err)) } err = c.RemoveDir(f.dirFromStandardPath(path.Join(f.root, dir))) f.putFtpConnection(&c, err) @@ -888,11 +889,11 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } err := f.mkParentDir(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "Move mkParentDir failed") + return nil, fmt.Errorf("Move mkParentDir failed: %w", err) } c, err := f.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "Move") + return nil, fmt.Errorf("Move: %w", err) } err = c.Rename( f.opt.Enc.FromStandardPath(path.Join(srcObj.fs.root, srcObj.remote)), @@ -900,11 +901,11 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, ) f.putFtpConnection(&c, err) if err != nil { - return nil, errors.Wrap(err, "Move Rename failed") + return nil, fmt.Errorf("Move Rename failed: %w", err) } dstObj, err := f.NewObject(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "Move NewObject failed") + return nil, fmt.Errorf("Move NewObject failed: %w", err) } return dstObj, nil } @@ -934,19 +935,19 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string } return fs.ErrorIsFile } else if err != fs.ErrorObjectNotFound { - return errors.Wrapf(err, "DirMove getInfo failed") + return fmt.Errorf("DirMove getInfo failed: %w", err) } // Make sure the parent directory exists err = f.mkdir(ctx, path.Dir(dstPath)) if err != nil { - return errors.Wrap(err, "DirMove mkParentDir dst failed") + return fmt.Errorf("DirMove mkParentDir dst failed: %w", err) } // Do the move c, err := f.getFtpConnection(ctx) if err != nil { - return errors.Wrap(err, "DirMove") + return fmt.Errorf("DirMove: %w", err) } err = c.Rename( f.dirFromStandardPath(srcPath), @@ -954,7 +955,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string ) f.putFtpConnection(&c, err) if err != nil { - return errors.Wrapf(err, "DirMove Rename(%q,%q) failed", srcPath, dstPath) + return fmt.Errorf("DirMove Rename(%q,%q) failed: %w", srcPath, dstPath, err) } return nil } @@ -1111,12 +1112,12 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (rc io.Read } c, err := o.fs.getFtpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "open") + return nil, fmt.Errorf("open: %w", err) } fd, err := c.RetrFrom(o.fs.opt.Enc.FromStandardPath(path), uint64(offset)) if err != nil { o.fs.putFtpConnection(&c, err) - return nil, errors.Wrap(err, "open") + return nil, fmt.Errorf("open: %w", err) } rc = &ftpReadCloser{rc: readers.NewLimitedReadCloser(fd, limit), c: c, f: o.fs} return rc, nil @@ -1146,7 +1147,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } c, err := o.fs.getFtpConnection(ctx) if err != nil { - return errors.Wrap(err, "Update") + return fmt.Errorf("Update: %w", err) } err = c.Stor(o.fs.opt.Enc.FromStandardPath(path), in) // Ignore error 250 here - send by some servers @@ -1164,15 +1165,15 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // recycle connection in advance to let remove() find free token o.fs.putFtpConnection(nil, err) remove() - return errors.Wrap(err, "update stor") + return fmt.Errorf("update stor: %w", err) } o.fs.putFtpConnection(&c, nil) if err = o.SetModTime(ctx, src.ModTime(ctx)); err != nil { - return errors.Wrap(err, "SetModTime") + return fmt.Errorf("SetModTime: %w", err) } o.info, err = o.fs.getInfo(ctx, path) if err != nil { - return errors.Wrap(err, "update getinfo") + return fmt.Errorf("update getinfo: %w", err) } return nil } @@ -1191,7 +1192,7 @@ func (o *Object) Remove(ctx context.Context) (err error) { } else { c, err := o.fs.getFtpConnection(ctx) if err != nil { - return errors.Wrap(err, "Remove") + return fmt.Errorf("Remove: %w", err) } err = c.Delete(o.fs.opt.Enc.FromStandardPath(path)) o.fs.putFtpConnection(&c, err) diff --git a/backend/googlecloudstorage/googlecloudstorage.go b/backend/googlecloudstorage/googlecloudstorage.go index 2e8b5125c..0a4442bde 100644 --- a/backend/googlecloudstorage/googlecloudstorage.go +++ b/backend/googlecloudstorage/googlecloudstorage.go @@ -16,6 +16,7 @@ import ( "context" "encoding/base64" "encoding/hex" + "errors" "fmt" "io" "io/ioutil" @@ -25,7 +26,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -375,7 +375,7 @@ func (o *Object) split() (bucket, bucketPath string) { func getServiceAccountClient(ctx context.Context, credentialsData []byte) (*http.Client, error) { conf, err := google.JWTConfigFromJSON(credentialsData, storageConfig.Scopes...) if err != nil { - return nil, errors.Wrap(err, "error processing credentials") + return nil, fmt.Errorf("error processing credentials: %w", err) } ctxWithSpecialClient := oauthutil.Context(ctx, fshttp.NewClient(ctx)) return oauth2.NewClient(ctxWithSpecialClient, conf.TokenSource(ctxWithSpecialClient)), nil @@ -408,7 +408,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.ServiceAccountCredentials == "" && opt.ServiceAccountFile != "" { loadedCreds, err := ioutil.ReadFile(env.ShellExpand(opt.ServiceAccountFile)) if err != nil { - return nil, errors.Wrap(err, "error opening service account credentials file") + return nil, fmt.Errorf("error opening service account credentials file: %w", err) } opt.ServiceAccountCredentials = string(loadedCreds) } @@ -417,7 +417,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } else if opt.ServiceAccountCredentials != "" { oAuthClient, err = getServiceAccountClient(ctx, []byte(opt.ServiceAccountCredentials)) if err != nil { - return nil, errors.Wrap(err, "failed configuring Google Cloud Storage Service Account") + return nil, fmt.Errorf("failed configuring Google Cloud Storage Service Account: %w", err) } } else { oAuthClient, _, err = oauthutil.NewClient(ctx, name, m, storageConfig) @@ -425,7 +425,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e ctx := context.Background() oAuthClient, err = google.DefaultClient(ctx, storage.DevstorageFullControlScope) if err != nil { - return nil, errors.Wrap(err, "failed to configure Google Cloud Storage") + return nil, fmt.Errorf("failed to configure Google Cloud Storage: %w", err) } } } @@ -449,7 +449,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e f.client = oAuthClient f.svc, err = storage.New(f.client) if err != nil { - return nil, errors.Wrap(err, "couldn't create Google Cloud Storage client") + return nil, fmt.Errorf("couldn't create Google Cloud Storage client: %w", err) } if f.rootBucket != "" && f.rootDirectory != "" { @@ -759,10 +759,10 @@ func (f *Fs) makeBucket(ctx context.Context, bucket string) (err error) { return nil } else if gErr, ok := err.(*googleapi.Error); ok { if gErr.Code != http.StatusNotFound { - return errors.Wrap(err, "failed to get bucket") + return fmt.Errorf("failed to get bucket: %w", err) } } else { - return errors.Wrap(err, "failed to get bucket") + return fmt.Errorf("failed to get bucket: %w", err) } if f.opt.ProjectNumber == "" { @@ -1065,7 +1065,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read _, isRanging := req.Header["Range"] if !(res.StatusCode == http.StatusOK || (isRanging && res.StatusCode == http.StatusPartialContent)) { _ = res.Body.Close() // ignore error - return nil, errors.Errorf("bad response: %d: %s", res.StatusCode, res.Status) + return nil, fmt.Errorf("bad response: %d: %s", res.StatusCode, res.Status) } return res.Body, nil } diff --git a/backend/googlephotos/googlephotos.go b/backend/googlephotos/googlephotos.go index 9bd4fd44d..7a07356be 100644 --- a/backend/googlephotos/googlephotos.go +++ b/backend/googlephotos/googlephotos.go @@ -6,6 +6,7 @@ package googlephotos import ( "context" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -17,7 +18,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/googlephotos/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -85,7 +85,7 @@ func init() { opt := new(Options) err := configstruct.Set(m, opt) if err != nil { - return nil, errors.Wrap(err, "couldn't parse config into struct") + return nil, fmt.Errorf("couldn't parse config into struct: %w", err) } switch config.State { @@ -292,7 +292,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e baseClient := fshttp.NewClient(ctx) oAuthClient, ts, err := oauthutil.NewClientWithBaseClient(ctx, name, m, oauthConfig, baseClient) if err != nil { - return nil, errors.Wrap(err, "failed to configure Box") + return nil, fmt.Errorf("failed to configure Box: %w", err) } root = strings.Trim(path.Clean(root), "/") @@ -345,13 +345,13 @@ func (f *Fs) fetchEndpoint(ctx context.Context, name string) (endpoint string, e return shouldRetry(ctx, resp, err) }) if err != nil { - return "", errors.Wrap(err, "couldn't read openID config") + return "", fmt.Errorf("couldn't read openID config: %w", err) } // Find userinfo endpoint endpoint, ok := openIDconfig[name].(string) if !ok { - return "", errors.Errorf("couldn't find %q from openID config", name) + return "", fmt.Errorf("couldn't find %q from openID config", name) } return endpoint, nil @@ -374,7 +374,7 @@ func (f *Fs) UserInfo(ctx context.Context) (userInfo map[string]string, err erro return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't read user info") + return nil, fmt.Errorf("couldn't read user info: %w", err) } return userInfo, nil } @@ -405,7 +405,7 @@ func (f *Fs) Disconnect(ctx context.Context) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't revoke token") + return fmt.Errorf("couldn't revoke token: %w", err) } fs.Infof(f, "res = %+v", res) return nil @@ -492,7 +492,7 @@ func (f *Fs) listAlbums(ctx context.Context, shared bool) (all *albums, err erro return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't list albums") + return nil, fmt.Errorf("couldn't list albums: %w", err) } newAlbums := result.Albums if shared { @@ -549,7 +549,7 @@ func (f *Fs) list(ctx context.Context, filter api.SearchFilter, fn listFn) (err return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't list files") + return fmt.Errorf("couldn't list files: %w", err) } items := result.MediaItems if len(items) > 0 && items[0].ID == lastID { @@ -693,7 +693,7 @@ func (f *Fs) createAlbum(ctx context.Context, albumTitle string) (album *api.Alb return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't create album") + return nil, fmt.Errorf("couldn't create album: %w", err) } f.albums[false].add(&result) return &result, nil @@ -879,7 +879,7 @@ func (o *Object) readMetaData(ctx context.Context) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't get media item") + return fmt.Errorf("couldn't get media item: %w", err) } o.setMetaData(&item) return nil @@ -1014,7 +1014,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't upload file") + return fmt.Errorf("couldn't upload file: %w", err) } uploadToken := strings.TrimSpace(string(token)) if uploadToken == "" { @@ -1042,14 +1042,14 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to create media item") + return fmt.Errorf("failed to create media item: %w", err) } if len(result.NewMediaItemResults) != 1 { return errors.New("bad response to BatchCreate wrong number of items") } mediaItemResult := result.NewMediaItemResults[0] if mediaItemResult.Status.Code != 0 { - return errors.Errorf("upload failed: %s (%d)", mediaItemResult.Status.Message, mediaItemResult.Status.Code) + return fmt.Errorf("upload failed: %s (%d)", mediaItemResult.Status.Message, mediaItemResult.Status.Code) } o.setMetaData(&mediaItemResult.MediaItem) @@ -1071,7 +1071,7 @@ func (o *Object) Remove(ctx context.Context) (err error) { albumTitle, fileName := match[1], match[2] album, ok := o.fs.albums[false].get(albumTitle) if !ok { - return errors.Errorf("couldn't file %q in album %q for delete", fileName, albumTitle) + return fmt.Errorf("couldn't file %q in album %q for delete", fileName, albumTitle) } opts := rest.Opts{ Method: "POST", @@ -1087,7 +1087,7 @@ func (o *Object) Remove(ctx context.Context) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't delete item from album") + return fmt.Errorf("couldn't delete item from album: %w", err) } return nil } diff --git a/backend/googlephotos/pattern.go b/backend/googlephotos/pattern.go index a0e5f695e..e2cbcbf72 100644 --- a/backend/googlephotos/pattern.go +++ b/backend/googlephotos/pattern.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/googlephotos/api" "github.com/rclone/rclone/fs" ) @@ -270,7 +269,7 @@ func days(ctx context.Context, f lister, prefix string, match []string) (entries year := match[1] current, err := time.Parse("2006", year) if err != nil { - return nil, errors.Errorf("bad year %q", match[1]) + return nil, fmt.Errorf("bad year %q", match[1]) } currentYear := current.Year() for current.Year() == currentYear { @@ -284,7 +283,7 @@ func days(ctx context.Context, f lister, prefix string, match []string) (entries func yearMonthDayFilter(ctx context.Context, f lister, match []string) (sf api.SearchFilter, err error) { year, err := strconv.Atoi(match[1]) if err != nil || year < 1000 || year > 3000 { - return sf, errors.Errorf("bad year %q", match[1]) + return sf, fmt.Errorf("bad year %q", match[1]) } sf = api.SearchFilter{ Filters: &api.Filters{ @@ -300,14 +299,14 @@ func yearMonthDayFilter(ctx context.Context, f lister, match []string) (sf api.S if len(match) >= 3 { month, err := strconv.Atoi(match[2]) if err != nil || month < 1 || month > 12 { - return sf, errors.Errorf("bad month %q", match[2]) + return sf, fmt.Errorf("bad month %q", match[2]) } sf.Filters.DateFilter.Dates[0].Month = month } if len(match) >= 4 { day, err := strconv.Atoi(match[3]) if err != nil || day < 1 || day > 31 { - return sf, errors.Errorf("bad day %q", match[3]) + return sf, fmt.Errorf("bad day %q", match[3]) } sf.Filters.DateFilter.Dates[0].Day = day } diff --git a/backend/hasher/commands.go b/backend/hasher/commands.go index 99101daba..536981953 100644 --- a/backend/hasher/commands.go +++ b/backend/hasher/commands.go @@ -2,9 +2,10 @@ package hasher import ( "context" + "errors" + "fmt" "path" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/cache" @@ -118,18 +119,18 @@ func (f *Fs) dbImport(ctx context.Context, hashName, sumRemote string, sticky bo case fs.ErrorIsFile: // ok case nil: - return errors.Errorf("not a file: %s", sumRemote) + return fmt.Errorf("not a file: %s", sumRemote) default: return err } sumObj, err := sumFs.NewObject(ctx, path.Base(sumPath)) if err != nil { - return errors.Wrap(err, "cannot open sum file") + return fmt.Errorf("cannot open sum file: %w", err) } hashes, err := operations.ParseSumFile(ctx, sumObj) if err != nil { - return errors.Wrap(err, "failed to parse sum file") + return fmt.Errorf("failed to parse sum file: %w", err) } if sticky { diff --git a/backend/hasher/hasher.go b/backend/hasher/hasher.go index 1a7df38fc..2d94895ee 100644 --- a/backend/hasher/hasher.go +++ b/backend/hasher/hasher.go @@ -4,6 +4,7 @@ package hasher import ( "context" "encoding/gob" + "errors" "fmt" "io" "path" @@ -11,7 +12,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/config/configmap" @@ -102,7 +102,7 @@ func NewFs(ctx context.Context, fsname, rpath string, cmap configmap.Mapper) (fs remotePath := fspath.JoinRootPath(opt.Remote, rpath) baseFs, err := cache.Get(ctx, remotePath) if err != nil && err != fs.ErrorIsFile { - return nil, errors.Wrapf(err, "failed to derive base remote %q", opt.Remote) + return nil, fmt.Errorf("failed to derive base remote %q: %w", opt.Remote, err) } f := &Fs{ @@ -127,7 +127,7 @@ func NewFs(ctx context.Context, fsname, rpath string, cmap configmap.Mapper) (fs for _, hashName := range opt.Hashes { var ht hash.Type if err := ht.Set(hashName); err != nil { - return nil, errors.Errorf("invalid token %q in hash string %q", hashName, opt.Hashes.String()) + return nil, fmt.Errorf("invalid token %q in hash string %q", hashName, opt.Hashes.String()) } if !f.slowHashes.Contains(ht) { f.autoHashes.Add(ht) diff --git a/backend/hasher/kv.go b/backend/hasher/kv.go index 881661b4f..4f6754796 100644 --- a/backend/hasher/kv.go +++ b/backend/hasher/kv.go @@ -4,11 +4,11 @@ import ( "bytes" "context" "encoding/gob" + "errors" "fmt" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/operations" @@ -199,10 +199,10 @@ func (op *kvPut) Do(ctx context.Context, b kv.Bucket) (err error) { r.Hashes[hashType] = hashVal } if data, err = r.encode(op.key); err != nil { - return errors.Wrap(err, "marshal failed") + return fmt.Errorf("marshal failed: %w", err) } if err = b.Put([]byte(op.key), data); err != nil { - return errors.Wrap(err, "put failed") + return fmt.Errorf("put failed: %w", err) } return err } diff --git a/backend/hasher/object.go b/backend/hasher/object.go index 3c6e5af78..1233740e6 100644 --- a/backend/hasher/object.go +++ b/backend/hasher/object.go @@ -2,13 +2,13 @@ package hasher import ( "context" + "errors" "fmt" "io" "io/ioutil" "path" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/operations" diff --git a/backend/http/http.go b/backend/http/http.go index 8b68b0034..47a878bb3 100644 --- a/backend/http/http.go +++ b/backend/http/http.go @@ -6,6 +6,8 @@ package http import ( "context" + "errors" + "fmt" "io" "mime" "net/http" @@ -16,7 +18,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" @@ -132,7 +133,7 @@ func statusError(res *http.Response, err error) error { } if res.StatusCode < 200 || res.StatusCode > 299 { _ = res.Body.Close() - return errors.Errorf("HTTP Error %d: %s", res.StatusCode, res.Status) + return fmt.Errorf("HTTP Error %d: %s", res.StatusCode, res.Status) } return nil } @@ -377,15 +378,15 @@ func (f *Fs) readDir(ctx context.Context, dir string) (names []string, err error URL := f.url(dir) u, err := url.Parse(URL) if err != nil { - return nil, errors.Wrap(err, "failed to readDir") + return nil, fmt.Errorf("failed to readDir: %w", err) } if !strings.HasSuffix(URL, "/") { - return nil, errors.Errorf("internal error: readDir URL %q didn't end in /", URL) + return nil, fmt.Errorf("internal error: readDir URL %q didn't end in /", URL) } // Do the request req, err := http.NewRequestWithContext(ctx, "GET", URL, nil) if err != nil { - return nil, errors.Wrap(err, "readDir failed") + return nil, fmt.Errorf("readDir failed: %w", err) } f.addHeaders(req) res, err := f.httpClient.Do(req) @@ -397,7 +398,7 @@ func (f *Fs) readDir(ctx context.Context, dir string) (names []string, err error } err = statusError(res, err) if err != nil { - return nil, errors.Wrap(err, "failed to readDir") + return nil, fmt.Errorf("failed to readDir: %w", err) } contentType := strings.SplitN(res.Header.Get("Content-Type"), ";", 2)[0] @@ -405,10 +406,10 @@ func (f *Fs) readDir(ctx context.Context, dir string) (names []string, err error case "text/html": names, err = parse(u, res.Body) if err != nil { - return nil, errors.Wrap(err, "readDir") + return nil, fmt.Errorf("readDir: %w", err) } default: - return nil, errors.Errorf("Can't parse content type %q", contentType) + return nil, fmt.Errorf("Can't parse content type %q", contentType) } return names, nil } @@ -428,7 +429,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e } names, err := f.readDir(ctx, dir) if err != nil { - return nil, errors.Wrapf(err, "error listing %q", dir) + return nil, fmt.Errorf("error listing %q: %w", dir, err) } var ( entriesMu sync.Mutex // to protect entries @@ -540,7 +541,7 @@ func (o *Object) stat(ctx context.Context) error { url := o.url() req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) if err != nil { - return errors.Wrap(err, "stat failed") + return fmt.Errorf("stat failed: %w", err) } o.fs.addHeaders(req) res, err := o.fs.httpClient.Do(req) @@ -549,7 +550,7 @@ func (o *Object) stat(ctx context.Context) error { } err = statusError(res, err) if err != nil { - return errors.Wrap(err, "failed to stat") + return fmt.Errorf("failed to stat: %w", err) } t, err := http.ParseTime(res.Header.Get("Last-Modified")) if err != nil { @@ -562,7 +563,7 @@ func (o *Object) stat(ctx context.Context) error { if o.fs.opt.NoSlash { mediaType, _, err := mime.ParseMediaType(o.contentType) if err != nil { - return errors.Wrapf(err, "failed to parse Content-Type: %q", o.contentType) + return fmt.Errorf("failed to parse Content-Type: %q: %w", o.contentType, err) } if mediaType == "text/html" { return fs.ErrorNotAFile @@ -588,7 +589,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read url := o.url() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { - return nil, errors.Wrap(err, "Open failed") + return nil, fmt.Errorf("Open failed: %w", err) } // Add optional headers @@ -601,7 +602,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read res, err := o.fs.httpClient.Do(req) err = statusError(res, err) if err != nil { - return nil, errors.Wrap(err, "Open failed") + return nil, fmt.Errorf("Open failed: %w", err) } return res.Body, nil } diff --git a/backend/hubic/hubic.go b/backend/hubic/hubic.go index fcd43ad7f..ccf828ea3 100644 --- a/backend/hubic/hubic.go +++ b/backend/hubic/hubic.go @@ -9,6 +9,7 @@ package hubic import ( "context" "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" @@ -16,7 +17,6 @@ import ( "time" swiftLib "github.com/ncw/swift/v2" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/swift" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" @@ -120,7 +120,7 @@ func (f *Fs) getCredentials(ctx context.Context) (err error) { if resp.StatusCode < 200 || resp.StatusCode > 299 { body, _ := ioutil.ReadAll(resp.Body) bodyStr := strings.TrimSpace(strings.Replace(string(body), "\n", " ", -1)) - return errors.Errorf("failed to get credentials: %s: %s", resp.Status, bodyStr) + return fmt.Errorf("failed to get credentials: %s: %s", resp.Status, bodyStr) } decoder := json.NewDecoder(resp.Body) var result credentials @@ -146,7 +146,7 @@ func (f *Fs) getCredentials(ctx context.Context) (err error) { func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) { client, _, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure Hubic") + return nil, fmt.Errorf("failed to configure Hubic: %w", err) } f := &Fs{ @@ -163,7 +163,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = c.Authenticate(ctx) if err != nil { - return nil, errors.Wrap(err, "error authenticating swift connection") + return nil, fmt.Errorf("error authenticating swift connection: %w", err) } // Parse config into swift.Options struct diff --git a/backend/jottacloud/api/types.go b/backend/jottacloud/api/types.go index 83dbf01a8..db1e22aa6 100644 --- a/backend/jottacloud/api/types.go +++ b/backend/jottacloud/api/types.go @@ -2,10 +2,9 @@ package api import ( "encoding/xml" + "errors" "fmt" "time" - - "github.com/pkg/errors" ) const ( diff --git a/backend/jottacloud/jottacloud.go b/backend/jottacloud/jottacloud.go index 64898d9f6..6fa0329e9 100644 --- a/backend/jottacloud/jottacloud.go +++ b/backend/jottacloud/jottacloud.go @@ -7,6 +7,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -19,7 +20,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/jottacloud/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -146,12 +146,12 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf srv := rest.NewClient(fshttp.NewClient(ctx)) token, tokenEndpoint, err := doTokenAuth(ctx, srv, loginToken) if err != nil { - return nil, errors.Wrap(err, "failed to get oauth token") + return nil, fmt.Errorf("failed to get oauth token: %w", err) } m.Set(configTokenURL, tokenEndpoint) err = oauthutil.PutToken(name, m, &token, true) if err != nil { - return nil, errors.Wrap(err, "error while saving token") + return nil, fmt.Errorf("error while saving token: %w", err) } return fs.ConfigGoto("choose_device") case "legacy": // configure a jottacloud backend using legacy authentication @@ -168,7 +168,7 @@ machines.`) if config.Result == "true" { deviceRegistration, err := registerDevice(ctx, srv) if err != nil { - return nil, errors.Wrap(err, "failed to register device") + return nil, fmt.Errorf("failed to register device: %w", err) } m.Set(configClientID, deviceRegistration.ClientID) m.Set(configClientSecret, obscure.MustObscure(deviceRegistration.ClientSecret)) @@ -216,11 +216,11 @@ machines.`) m.Set("password", "") m.Set("auth_code", "") if err != nil { - return nil, errors.Wrap(err, "failed to get oauth token") + return nil, fmt.Errorf("failed to get oauth token: %w", err) } err = oauthutil.PutToken(name, m, &token, true) if err != nil { - return nil, errors.Wrap(err, "error while saving token") + return nil, fmt.Errorf("error while saving token: %w", err) } return fs.ConfigGoto("choose_device") case "telia": // telia cloud config @@ -529,7 +529,7 @@ func getCustomerInfo(ctx context.Context, apiSrv *rest.Client) (info *api.Custom _, err = apiSrv.CallJSON(ctx, &opts, nil, &info) if err != nil { - return nil, errors.Wrap(err, "couldn't get customer info") + return nil, fmt.Errorf("couldn't get customer info: %w", err) } return info, nil @@ -544,7 +544,7 @@ func getDriveInfo(ctx context.Context, srv *rest.Client, username string) (info _, err = srv.CallXML(ctx, &opts, nil, &info) if err != nil { - return nil, errors.Wrap(err, "couldn't get drive info") + return nil, fmt.Errorf("couldn't get drive info: %w", err) } return info, nil @@ -559,7 +559,7 @@ func getDeviceInfo(ctx context.Context, srv *rest.Client, path string) (info *ap _, err = srv.CallXML(ctx, &opts, nil, &info) if err != nil { - return nil, errors.Wrap(err, "couldn't get device info") + return nil, fmt.Errorf("couldn't get device info: %w", err) } return info, nil @@ -597,7 +597,7 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, path string) (info *api.Jo } if err != nil { - return nil, errors.Wrap(err, "read metadata failed") + return nil, fmt.Errorf("read metadata failed: %w", err) } if result.XMLName.Local == "folder" { return nil, fs.ErrorIsDir @@ -720,7 +720,7 @@ func getOAuthClient(ctx context.Context, name string, m configmap.Mapper) (oAuth // Create OAuth Client oAuthClient, ts, err = oauthutil.NewClientWithBaseClient(ctx, name, m, oauthConfig, baseClient) if err != nil { - return nil, nil, errors.Wrap(err, "Failed to configure Jottacloud oauth client") + return nil, nil, fmt.Errorf("Failed to configure Jottacloud oauth client: %w", err) } return oAuthClient, ts, nil } @@ -786,7 +786,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } _, err := f.NewObject(context.TODO(), remote) if err != nil { - if uErr := errors.Cause(err); uErr == fs.ErrorObjectNotFound || uErr == fs.ErrorNotAFile || uErr == fs.ErrorIsDir { + if errors.Is(err, fs.ErrorObjectNotFound) || errors.Is(err, fs.ErrorNotAFile) || errors.Is(err, fs.ErrorIsDir) { // File doesn't exist so return old f f.root = root return f, nil @@ -881,7 +881,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e return nil, fs.ErrorDirNotFound } } - return nil, errors.Wrap(err, "couldn't list files") + return nil, fmt.Errorf("couldn't list files: %w", err) } if !f.validFolder(&result) { @@ -981,7 +981,7 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) ( return fs.ErrorDirNotFound } } - return errors.Wrap(err, "couldn't list files") + return fmt.Errorf("couldn't list files: %w", err) } list := walk.NewListRHelper(callback) err = f.listFileDir(ctx, dir, &result, func(entry fs.DirEntry) error { @@ -1081,7 +1081,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) (err error) return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't purge directory") + return fmt.Errorf("couldn't purge directory: %w", err) } return nil @@ -1148,7 +1148,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, info, err := f.copyOrMove(ctx, "cp", srcObj.filePath(), remote) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } return f.newObjectWithInfo(ctx, remote, info) @@ -1178,7 +1178,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, info, err := f.copyOrMove(ctx, "mv", srcObj.filePath(), remote) if err != nil { - return nil, errors.Wrap(err, "couldn't move file") + return nil, fmt.Errorf("couldn't move file: %w", err) } return f.newObjectWithInfo(ctx, remote, info) @@ -1222,7 +1222,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string _, err = f.copyOrMove(ctx, "mvDir", path.Join(f.endpointURL, f.opt.Enc.FromStandardPath(srcPath))+"/", dstRemote) if err != nil { - return errors.Wrap(err, "couldn't move directory") + return fmt.Errorf("couldn't move directory: %w", err) } return nil } @@ -1256,13 +1256,13 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, } if err != nil { if unlink { - return "", errors.Wrap(err, "couldn't remove public link") + return "", fmt.Errorf("couldn't remove public link: %w", err) } - return "", errors.Wrap(err, "couldn't create public link") + return "", fmt.Errorf("couldn't create public link: %w", err) } if unlink { if result.PublicURI != "" { - return "", errors.Errorf("couldn't remove public link - %q", result.PublicURI) + return "", fmt.Errorf("couldn't remove public link - %q", result.PublicURI) } return "", nil } @@ -1322,7 +1322,7 @@ func (f *Fs) CleanUp(ctx context.Context) error { var info api.TrashResponse _, err := f.apiSrv.CallJSON(ctx, &opts, nil, &info) if err != nil { - return errors.Wrap(err, "couldn't empty trash") + return fmt.Errorf("couldn't empty trash: %w", err) } return nil @@ -1584,7 +1584,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // if the object exists delete it err = o.remove(ctx, true) if err != nil { - return errors.Wrap(err, "failed to remove old object") + return fmt.Errorf("failed to remove old object: %w", err) } } // if the object does not exist we can just continue but if the error is something different we should report that @@ -1605,7 +1605,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op md5String, in, cleanup, err = readMD5(in, size, int64(o.fs.opt.MD5MemoryThreshold)) defer cleanup() if err != nil { - return errors.Wrap(err, "failed to calculate MD5") + return fmt.Errorf("failed to calculate MD5: %w", err) } // Wrap the accounting back onto the stream in = wrap(in) diff --git a/backend/local/about_unix.go b/backend/local/about_unix.go index 427c62872..86f28d74f 100644 --- a/backend/local/about_unix.go +++ b/backend/local/about_unix.go @@ -5,10 +5,10 @@ package local import ( "context" + "fmt" "os" "syscall" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -20,7 +20,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { if os.IsNotExist(err) { return nil, fs.ErrorDirNotFound } - return nil, errors.Wrap(err, "failed to read disk usage") + return nil, fmt.Errorf("failed to read disk usage: %w", err) } bs := int64(s.Bsize) // nolint: unconvert usage := &fs.Usage{ diff --git a/backend/local/about_windows.go b/backend/local/about_windows.go index cc8332534..d8daed764 100644 --- a/backend/local/about_windows.go +++ b/backend/local/about_windows.go @@ -5,10 +5,10 @@ package local import ( "context" + "fmt" "syscall" "unsafe" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -24,7 +24,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { uintptr(unsafe.Pointer(&free)), // lpTotalNumberOfFreeBytes ) if e1 != syscall.Errno(0) { - return nil, errors.Wrap(e1, "failed to read disk usage") + return nil, fmt.Errorf("failed to read disk usage: %w", e1) } usage := &fs.Usage{ Total: fs.NewUsageValue(total), // quota of bytes that can be used diff --git a/backend/local/local.go b/backend/local/local.go index 90f3e9a3f..5dc65ec6a 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -4,6 +4,7 @@ package local import ( "bytes" "context" + "errors" "fmt" "io" "io/ioutil" @@ -16,7 +17,6 @@ import ( "time" "unicode/utf8" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/config" @@ -432,7 +432,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e fd, err := os.Open(fsDirPath) if err != nil { isPerm := os.IsPermission(err) - err = errors.Wrapf(err, "failed to open directory %q", dir) + err = fmt.Errorf("failed to open directory %q: %w", dir, err) fs.Errorf(dir, "%v", err) if isPerm { _ = accounting.Stats(ctx).Error(fserrors.NoRetryError(err)) @@ -443,7 +443,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e defer func() { cerr := fd.Close() if cerr != nil && err == nil { - err = errors.Wrapf(cerr, "failed to close directory %q:", dir) + err = fmt.Errorf("failed to close directory %q:: %w", dir, cerr) } }() @@ -473,7 +473,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e continue } if fierr != nil { - err = errors.Wrapf(err, "failed to read directory %q", namepath) + err = fmt.Errorf("failed to read directory %q: %w", namepath, err) fs.Errorf(dir, "%v", fierr) _ = accounting.Stats(ctx).Error(fserrors.NoRetryError(fierr)) // fail the sync continue @@ -483,7 +483,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e } } if err != nil { - return nil, errors.Wrap(err, "failed to read directory entry") + return nil, fmt.Errorf("failed to read directory entry: %w", err) } for _, fi := range fis { @@ -496,7 +496,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e fi, err = os.Stat(localPath) if os.IsNotExist(err) || isCircularSymlinkError(err) { // Skip bad symlinks and circular symlinks - err = fserrors.NoRetryError(errors.Wrap(err, "symlink")) + err = fserrors.NoRetryError(fmt.Errorf("symlink: %w", err)) fs.Errorf(newRemote, "Listing error: %v", err) err = accounting.Stats(ctx).Error(err) continue @@ -672,7 +672,7 @@ func (f *Fs) Purge(ctx context.Context, dir string) error { return err } if !fi.Mode().IsDir() { - return errors.Errorf("can't purge non directory: %q", dir) + return fmt.Errorf("can't purge non directory: %q", dir) } return os.RemoveAll(dir) } @@ -866,12 +866,12 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) { err := o.lstat() var changed bool if err != nil { - if os.IsNotExist(errors.Cause(err)) { + if errors.Is(err, os.ErrNotExist) { // If file not found then we assume any accumulated // hashes are OK - this will error on Open changed = true } else { - return "", errors.Wrap(err, "hash: failed to stat") + return "", fmt.Errorf("hash: failed to stat: %w", err) } } else { o.fs.objectMetaMu.RLock() @@ -900,16 +900,16 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) { in = readers.NewLimitedReadCloser(in, o.size) } if err != nil { - return "", errors.Wrap(err, "hash: failed to open") + return "", fmt.Errorf("hash: failed to open: %w", err) } var hashes map[hash.Type]string hashes, err = hash.StreamTypes(in, hash.NewHashSet(r)) closeErr := in.Close() if err != nil { - return "", errors.Wrap(err, "hash: failed to read") + return "", fmt.Errorf("hash: failed to read: %w", err) } if closeErr != nil { - return "", errors.Wrap(closeErr, "hash: failed to close") + return "", fmt.Errorf("hash: failed to close: %w", closeErr) } hashValue = hashes[r] o.fs.objectMetaMu.Lock() @@ -990,17 +990,17 @@ func (file *localOpenFile) Read(p []byte) (n int, err error) { // Check if file has the same size and modTime fi, err := file.fd.Stat() if err != nil { - return 0, errors.Wrap(err, "can't read status of source file while transferring") + return 0, fmt.Errorf("can't read status of source file while transferring: %w", err) } file.o.fs.objectMetaMu.RLock() oldtime := file.o.modTime oldsize := file.o.size file.o.fs.objectMetaMu.RUnlock() if oldsize != fi.Size() { - return 0, fserrors.NoLowLevelRetryError(errors.Errorf("can't copy - source file is being updated (size changed from %d to %d)", oldsize, fi.Size())) + return 0, fserrors.NoLowLevelRetryError(fmt.Errorf("can't copy - source file is being updated (size changed from %d to %d)", oldsize, fi.Size())) } if !oldtime.Equal(fi.ModTime()) { - return 0, fserrors.NoLowLevelRetryError(errors.Errorf("can't copy - source file is being updated (mod time changed from %v to %v)", oldtime, fi.ModTime())) + return 0, fserrors.NoLowLevelRetryError(fmt.Errorf("can't copy - source file is being updated (mod time changed from %v to %v)", oldtime, fi.ModTime())) } } diff --git a/backend/mailru/api/helpers.go b/backend/mailru/api/helpers.go index 2b4ebb3b5..1b43eb182 100644 --- a/backend/mailru/api/helpers.go +++ b/backend/mailru/api/helpers.go @@ -6,11 +6,11 @@ import ( "bufio" "bytes" "encoding/binary" + "errors" "fmt" "io" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/lib/readers" ) diff --git a/backend/mailru/mailru.go b/backend/mailru/mailru.go index 9aa969085..4551eeae7 100644 --- a/backend/mailru/mailru.go +++ b/backend/mailru/mailru.go @@ -3,6 +3,7 @@ package mailru import ( "bytes" "context" + "errors" "fmt" gohash "hash" "io" @@ -40,7 +41,6 @@ import ( "github.com/rclone/rclone/lib/readers" "github.com/rclone/rclone/lib/rest" - "github.com/pkg/errors" "golang.org/x/oauth2" ) @@ -438,7 +438,7 @@ func (f *Fs) authorize(ctx context.Context, force bool) (err error) { err = errors.New("Invalid token") } if err != nil { - return errors.Wrap(err, "Failed to authorize") + return fmt.Errorf("Failed to authorize: %w", err) } if err = oauthutil.PutToken(f.name, f.m, t, false); err != nil { @@ -507,7 +507,7 @@ func (f *Fs) reAuthorize(opts *rest.Opts, origErr error) error { func (f *Fs) accessToken() (string, error) { token, err := f.source.Token() if err != nil { - return "", errors.Wrap(err, "cannot refresh access token") + return "", fmt.Errorf("cannot refresh access token: %w", err) } return token.AccessToken, nil } @@ -1196,7 +1196,7 @@ func (f *Fs) purgeWithCheck(ctx context.Context, dir string, check bool, opName _, dirSize, err := f.readItemMetaData(ctx, path) if err != nil { - return errors.Wrapf(err, "%s failed", opName) + return fmt.Errorf("%s failed: %w", opName, err) } if check && dirSize > 0 { return fs.ErrorDirectoryNotEmpty @@ -1300,7 +1300,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, }) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } if response.Status != 200 { return nil, fmt.Errorf("copy failed with code %d", response.Status) @@ -1684,7 +1684,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op spoolFile, mrHash, err := makeTempFile(ctx, tmpFs, wrapIn, src) if err != nil { - return errors.Wrap(err, "Failed to create spool file") + return fmt.Errorf("Failed to create spool file: %w", err) } if o.putByHash(ctx, mrHash, src, "spool") { // If put by hash is successful, ignore transitive error @@ -2318,7 +2318,7 @@ func (p *serverPool) Dispatch(ctx context.Context, current string) (string, erro }) if err != nil || url == "" { closeBody(res) - return "", errors.Wrap(err, "Failed to request file server") + return "", fmt.Errorf("Failed to request file server: %w", err) } p.addServer(url, now) diff --git a/backend/mega/mega.go b/backend/mega/mega.go index 5615cd640..7b38fdf58 100644 --- a/backend/mega/mega.go +++ b/backend/mega/mega.go @@ -17,6 +17,7 @@ Improvements: import ( "context" + "errors" "fmt" "io" "path" @@ -24,7 +25,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -165,13 +165,6 @@ func shouldRetry(ctx context.Context, err error) (bool, error) { } // Let the mega library handle the low level retries return false, err - /* - switch errors.Cause(err) { - case mega.EAGAIN, mega.ERATELIMIT, mega.ETEMPUNAVAIL: - return true, err - } - return fserrors.ShouldRetry(err), err - */ } // readMetaDataForPath reads the metadata from the path @@ -195,7 +188,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e var err error opt.Pass, err = obscure.Reveal(opt.Pass) if err != nil { - return nil, errors.Wrap(err, "couldn't decrypt password") + return nil, fmt.Errorf("couldn't decrypt password: %w", err) } } ci := fs.GetConfig(ctx) @@ -222,7 +215,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e err := srv.Login(opt.User, opt.Pass) if err != nil { - return nil, errors.Wrap(err, "couldn't login") + return nil, fmt.Errorf("couldn't login: %w", err) } megaCache[opt.User] = srv } @@ -350,11 +343,11 @@ func (f *Fs) mkdir(ctx context.Context, rootNode *mega.Node, dir string) (node * break } if err != mega.ENOENT { - return nil, errors.Wrap(err, "mkdir lookup failed") + return nil, fmt.Errorf("mkdir lookup failed: %w", err) } } if err != nil { - return nil, errors.Wrap(err, "internal error: mkdir called with non-existent root node") + return nil, fmt.Errorf("internal error: mkdir called with non-existent root node: %w", err) } // i is number of directories to create (may be 0) // node is directory to create them from @@ -365,7 +358,7 @@ func (f *Fs) mkdir(ctx context.Context, rootNode *mega.Node, dir string) (node * return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "mkdir create node failed") + return nil, fmt.Errorf("mkdir create node failed: %w", err) } } return node, nil @@ -428,7 +421,7 @@ func (f *Fs) CleanUp(ctx context.Context) (err error) { return false }) if err != nil { - return errors.Wrap(err, "CleanUp failed to list items in trash") + return fmt.Errorf("CleanUp failed to list items in trash: %w", err) } fs.Infof(f, "Deleting %d items from the trash", len(items)) errors := 0 @@ -489,7 +482,7 @@ type listFn func(*mega.Node) bool func (f *Fs) list(ctx context.Context, dir *mega.Node, fn listFn) (found bool, err error) { nodes, err := f.srv.FS.GetChildren(dir) if err != nil { - return false, errors.Wrapf(err, "list failed") + return false, fmt.Errorf("list failed: %w", err) } for _, item := range nodes { if fn(item) { @@ -609,7 +602,7 @@ func (f *Fs) Mkdir(ctx context.Context, dir string) error { return err } _, err = f.mkdir(ctx, rootNode, dir) - return errors.Wrap(err, "Mkdir failed") + return fmt.Errorf("Mkdir failed: %w", err) } // deleteNode removes a file or directory, observing useTrash @@ -639,7 +632,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { if check { children, err := f.srv.FS.GetChildren(dirNode) if err != nil { - return errors.Wrap(err, "purgeCheck GetChildren failed") + return fmt.Errorf("purgeCheck GetChildren failed: %w", err) } if len(children) > 0 { return fs.ErrorDirectoryNotEmpty @@ -650,7 +643,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { err = f.deleteNode(ctx, dirNode) if err != nil { - return errors.Wrap(err, "delete directory node failed") + return fmt.Errorf("delete directory node failed: %w", err) } // Remove the root node if we just deleted it @@ -704,7 +697,7 @@ func (f *Fs) move(ctx context.Context, dstRemote string, srcFs *Fs, srcRemote st dstDirNode, err = dstFs.mkdir(ctx, absRoot, dstParent) } if err != nil { - return errors.Wrap(err, "server-side move failed to make dst parent dir") + return fmt.Errorf("server-side move failed to make dst parent dir: %w", err) } if srcRemote != "" { @@ -717,7 +710,7 @@ func (f *Fs) move(ctx context.Context, dstRemote string, srcFs *Fs, srcRemote st srcDirNode, err = f.findDir(absRoot, srcParent) } if err != nil { - return errors.Wrap(err, "server-side move failed to lookup src parent dir") + return fmt.Errorf("server-side move failed to lookup src parent dir: %w", err) } // move the object into its new directory if required @@ -728,7 +721,7 @@ func (f *Fs) move(ctx context.Context, dstRemote string, srcFs *Fs, srcRemote st return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "server-side move failed") + return fmt.Errorf("server-side move failed: %w", err) } } @@ -742,7 +735,7 @@ func (f *Fs) move(ctx context.Context, dstRemote string, srcFs *Fs, srcRemote st return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "server-side rename failed") + return fmt.Errorf("server-side rename failed: %w", err) } } @@ -812,7 +805,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string if err == nil { return fs.ErrorDirExists } else if err != fs.ErrorDirNotFound { - return errors.Wrap(err, "DirMove error while checking dest directory") + return fmt.Errorf("DirMove error while checking dest directory: %w", err) } // Do the move @@ -844,15 +837,15 @@ func (f *Fs) Hashes() hash.Set { func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, unlink bool) (link string, err error) { root, err := f.findRoot(ctx, false) if err != nil { - return "", errors.Wrap(err, "PublicLink failed to find root node") + return "", fmt.Errorf("PublicLink failed to find root node: %w", err) } node, err := f.findNode(root, remote) if err != nil { - return "", errors.Wrap(err, "PublicLink failed to find path") + return "", fmt.Errorf("PublicLink failed to find path: %w", err) } link, err = f.srv.Link(node, true) if err != nil { - return "", errors.Wrap(err, "PublicLink failed to create link") + return "", fmt.Errorf("PublicLink failed to create link: %w", err) } return link, nil } @@ -867,13 +860,13 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { dstDir := dirs[0] dstDirNode := f.srv.FS.HashLookup(dstDir.ID()) if dstDirNode == nil { - return errors.Errorf("MergeDirs failed to find node for: %v", dstDir) + return fmt.Errorf("MergeDirs failed to find node for: %v", dstDir) } for _, srcDir := range dirs[1:] { // find src directory srcDirNode := f.srv.FS.HashLookup(srcDir.ID()) if srcDirNode == nil { - return errors.Errorf("MergeDirs failed to find node for: %v", srcDir) + return fmt.Errorf("MergeDirs failed to find node for: %v", srcDir) } // list the objects @@ -883,7 +876,7 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { return false }) if err != nil { - return errors.Wrapf(err, "MergeDirs list failed on %v", srcDir) + return fmt.Errorf("MergeDirs list failed on %v: %w", srcDir, err) } // move them into place for _, info := range infos { @@ -893,14 +886,14 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrapf(err, "MergeDirs move failed on %q in %v", f.opt.Enc.ToStandardName(info.GetName()), srcDir) + return fmt.Errorf("MergeDirs move failed on %q in %v: %w", f.opt.Enc.ToStandardName(info.GetName()), srcDir, err) } } // rmdir (into trash) the now empty source directory fs.Infof(srcDir, "removing empty directory") err = f.deleteNode(ctx, srcDirNode) if err != nil { - return errors.Wrapf(err, "MergeDirs move failed to rmdir %q", srcDir) + return fmt.Errorf("MergeDirs move failed to rmdir %q: %w", srcDir, err) } } return nil @@ -915,7 +908,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get Mega Quota") + return nil, fmt.Errorf("failed to get Mega Quota: %w", err) } usage := &fs.Usage{ Total: fs.NewUsageValue(int64(q.Mstrg)), // quota of bytes that can be used @@ -1076,7 +1069,7 @@ func (oo *openObject) Close() (err error) { return shouldRetry(oo.ctx, err) }) if err != nil { - return errors.Wrap(err, "failed to finish download") + return fmt.Errorf("failed to finish download: %w", err) } oo.closed = true return nil @@ -1104,7 +1097,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "open download file failed") + return nil, fmt.Errorf("open download file failed: %w", err) } oo := &openObject{ @@ -1133,7 +1126,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // Create the parent directory dirNode, leaf, err := o.fs.mkdirParent(ctx, remote) if err != nil { - return errors.Wrap(err, "update make parent dir failed") + return fmt.Errorf("update make parent dir failed: %w", err) } var u *mega.Upload @@ -1142,7 +1135,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "upload file failed to create session") + return fmt.Errorf("upload file failed to create session: %w", err) } // Upload the chunks @@ -1150,12 +1143,12 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op for id := 0; id < u.Chunks(); id++ { _, chunkSize, err := u.ChunkLocation(id) if err != nil { - return errors.Wrap(err, "upload failed to read chunk location") + return fmt.Errorf("upload failed to read chunk location: %w", err) } chunk := make([]byte, chunkSize) _, err = io.ReadFull(in, chunk) if err != nil { - return errors.Wrap(err, "upload failed to read data") + return fmt.Errorf("upload failed to read data: %w", err) } err = o.fs.pacer.Call(func() (bool, error) { @@ -1163,7 +1156,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "upload file failed to upload chunk") + return fmt.Errorf("upload file failed to upload chunk: %w", err) } } @@ -1174,14 +1167,14 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "failed to finish upload") + return fmt.Errorf("failed to finish upload: %w", err) } // If the upload succeeded and the original object existed, then delete it if o.info != nil { err = o.fs.deleteNode(ctx, o.info) if err != nil { - return errors.Wrap(err, "upload failed to remove old version") + return fmt.Errorf("upload failed to remove old version: %w", err) } o.info = nil } @@ -1193,7 +1186,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op func (o *Object) Remove(ctx context.Context) error { err := o.fs.deleteNode(ctx, o.info) if err != nil { - return errors.Wrap(err, "Remove object failed") + return fmt.Errorf("Remove object failed: %w", err) } return nil } diff --git a/backend/memory/memory.go b/backend/memory/memory.go index 0ff851d45..9675abcd3 100644 --- a/backend/memory/memory.go +++ b/backend/memory/memory.go @@ -14,7 +14,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" @@ -586,7 +585,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op bucket, bucketPath := o.split() data, err := ioutil.ReadAll(in) if err != nil { - return errors.Wrap(err, "failed to update memory object") + return fmt.Errorf("failed to update memory object: %w", err) } o.od = &objectData{ data: data, diff --git a/backend/onedrive/onedrive.go b/backend/onedrive/onedrive.go old mode 100755 new mode 100644 index 7e0b0a823..d76e17a35 --- a/backend/onedrive/onedrive.go +++ b/backend/onedrive/onedrive.go @@ -7,6 +7,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -18,7 +19,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/onedrive/api" "github.com/rclone/rclone/backend/onedrive/quickxorhash" "github.com/rclone/rclone/fs" @@ -385,7 +385,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf oAuthClient, _, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure OneDrive") + return nil, fmt.Errorf("failed to configure OneDrive: %w", err) } srv := rest.NewClient(oAuthClient) @@ -754,10 +754,10 @@ func errorHandler(resp *http.Response) error { func checkUploadChunkSize(cs fs.SizeSuffix) error { const minChunkSize = fs.SizeSuffixBase if cs%chunkSizeMultiple != 0 { - return errors.Errorf("%s is not a multiple of %s", cs, chunkSizeMultiple) + return fmt.Errorf("%s is not a multiple of %s", cs, chunkSizeMultiple) } if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -781,7 +781,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "onedrive: chunk size") + return nil, fmt.Errorf("onedrive: chunk size: %w", err) } if opt.DriveID == "" || opt.DriveType == "" { @@ -797,7 +797,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e root = parsePath(root) oAuthClient, ts, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure OneDrive") + return nil, fmt.Errorf("failed to configure OneDrive: %w", err) } ci := fs.GetConfig(ctx) @@ -828,7 +828,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e // Get rootID rootInfo, _, err := f.readMetaDataForPath(ctx, "") if err != nil || rootInfo.GetID() == "" { - return nil, errors.Wrap(err, "failed to get root") + return nil, fmt.Errorf("failed to get root: %w", err) } f.dirCache = dircache.New(root, rootInfo.GetID(), f) @@ -971,7 +971,7 @@ OUTER: return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } if len(result.Value) == 0 { break @@ -1175,7 +1175,7 @@ func (f *Fs) waitForJob(ctx context.Context, location string, o *Object) error { var status api.AsyncOperationStatus err = json.Unmarshal(body, &status) if err != nil { - return errors.Wrapf(err, "async status result not JSON: %q", body) + return fmt.Errorf("async status result not JSON: %q: %w", body, err) } switch status.Status { @@ -1185,15 +1185,15 @@ func (f *Fs) waitForJob(ctx context.Context, location string, o *Object) error { } fallthrough case "deleteFailed": - return errors.Errorf("%s: async operation returned %q", o.remote, status.Status) + return fmt.Errorf("%s: async operation returned %q", o.remote, status.Status) case "completed": err = o.readMetaData(ctx) - return errors.Wrapf(err, "async operation completed but readMetaData failed") + return fmt.Errorf("async operation completed but readMetaData failed: %w", err) } time.Sleep(1 * time.Second) } - return errors.Errorf("async operation didn't complete after %v", f.ci.TimeoutOrInfinite()) + return fmt.Errorf("async operation didn't complete after %v", f.ci.TimeoutOrInfinite()) } // Copy src to this remote using server-side copy operations. @@ -1232,7 +1232,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, srcPath := srcObj.rootPath() dstPath := f.rootPath(remote) if strings.ToLower(srcPath) == strings.ToLower(dstPath) { - return nil, errors.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) + return nil, fmt.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) } } @@ -1450,7 +1450,7 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "about failed") + return nil, fmt.Errorf("about failed: %w", err) } q := drive.Quota // On (some?) Onedrive sharepoints these are all 0 so return unknown in that case @@ -1501,7 +1501,7 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, }) if err != nil { if resp != nil && resp.StatusCode == 400 && f.driveType != driveTypePersonal { - return "", errors.Errorf("%v (is making public links permitted by the org admin?)", err) + return "", fmt.Errorf("%v (is making public links permitted by the org admin?)", err) } return "", err } @@ -1886,17 +1886,17 @@ func (o *Object) getPosition(ctx context.Context, url string) (pos int64, err er return 0, err } if len(info.NextExpectedRanges) != 1 { - return 0, errors.Errorf("bad number of ranges in upload position: %v", info.NextExpectedRanges) + return 0, fmt.Errorf("bad number of ranges in upload position: %v", info.NextExpectedRanges) } position := info.NextExpectedRanges[0] i := strings.IndexByte(position, '-') if i < 0 { - return 0, errors.Errorf("no '-' in next expected range: %q", position) + return 0, fmt.Errorf("no '-' in next expected range: %q", position) } position = position[:i] pos, err = strconv.ParseInt(position, 10, 64) if err != nil { - return 0, errors.Wrapf(err, "bad expected range: %q", position) + return 0, fmt.Errorf("bad expected range: %q: %w", position, err) } return pos, nil } @@ -1930,14 +1930,14 @@ func (o *Object) uploadFragment(ctx context.Context, url string, start int64, to fs.Debugf(o, "Read position %d, chunk is %d..%d, bytes to skip = %d", pos, start, start+chunkSize, skip) switch { case skip < 0: - return false, errors.Wrapf(err, "sent block already (skip %d < 0), can't rewind", skip) + return false, fmt.Errorf("sent block already (skip %d < 0), can't rewind: %w", skip, err) case skip > chunkSize: - return false, errors.Wrapf(err, "position is in the future (skip %d > chunkSize %d), can't skip forward", skip, chunkSize) + return false, fmt.Errorf("position is in the future (skip %d > chunkSize %d), can't skip forward: %w", skip, chunkSize, err) case skip == chunkSize: fs.Debugf(o, "Skipping chunk as already sent (skip %d == chunkSize %d)", skip, chunkSize) return false, nil } - return true, errors.Wrapf(err, "retry this chunk skipping %d bytes", skip) + return true, fmt.Errorf("retry this chunk skipping %d bytes: %w", skip, err) } if err != nil { return shouldRetry(ctx, resp, err) diff --git a/backend/opendrive/opendrive.go b/backend/opendrive/opendrive.go index 00d83357e..96f29aa33 100644 --- a/backend/opendrive/opendrive.go +++ b/backend/opendrive/opendrive.go @@ -2,6 +2,7 @@ package opendrive import ( "context" + "errors" "fmt" "io" "net/http" @@ -11,7 +12,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -210,7 +210,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to create session") + return nil, fmt.Errorf("failed to create session: %w", err) } fs.Debugf(nil, "Starting OpenDrive session with ID: %s", f.session.SessionID) @@ -362,7 +362,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, srcPath := srcObj.fs.rootSlash() + srcObj.remote dstPath := f.rootSlash() + remote if strings.ToLower(srcPath) == strings.ToLower(dstPath) { - return nil, errors.Errorf("Can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) + return nil, fmt.Errorf("Can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) } // Create temporary object @@ -636,7 +636,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to create file") + return nil, fmt.Errorf("failed to create file: %w", err) } o.id = response.FileID @@ -719,7 +719,7 @@ func (f *Fs) FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut strin return f.shouldRetry(ctx, resp, err) }) if err != nil { - return "", false, errors.Wrap(err, "failed to get folder list") + return "", false, fmt.Errorf("failed to get folder list: %w", err) } leaf = f.opt.Enc.FromStandardName(leaf) @@ -762,7 +762,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get folder list") + return nil, fmt.Errorf("failed to get folder list: %w", err) } for _, folder := range folderList.Folders { @@ -871,7 +871,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to open file)") + return nil, fmt.Errorf("failed to open file): %w", err) } return resp.Body, nil @@ -919,7 +919,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to create file") + return fmt.Errorf("failed to create file: %w", err) } // resp.Body.Close() // fs.Debugf(nil, "PostOpen: %#v", openResponse) @@ -963,10 +963,10 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to create file") + return fmt.Errorf("failed to create file: %w", err) } if reply.TotalWritten != currentChunkSize { - return errors.Errorf("failed to create file: incomplete write of %d/%d bytes", reply.TotalWritten, currentChunkSize) + return fmt.Errorf("failed to create file: incomplete write of %d/%d bytes", reply.TotalWritten, currentChunkSize) } chunkCounter++ @@ -986,7 +986,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to create file") + return fmt.Errorf("failed to create file: %w", err) } // fs.Debugf(nil, "PostClose: %#v", closeResponse) @@ -1038,7 +1038,7 @@ func (o *Object) readMetaData(ctx context.Context) (err error) { return o.fs.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to get folder list") + return fmt.Errorf("failed to get folder list: %w", err) } if len(folderList.Files) == 0 { diff --git a/backend/pcloud/pcloud.go b/backend/pcloud/pcloud.go index f0ff23797..bb4c48653 100644 --- a/backend/pcloud/pcloud.go +++ b/backend/pcloud/pcloud.go @@ -10,6 +10,7 @@ package pcloud import ( "context" + "errors" "fmt" "io" "net/http" @@ -18,7 +19,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/pcloud/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -290,7 +290,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e root = parsePath(root) oAuthClient, ts, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure Pcloud") + return nil, fmt.Errorf("failed to configure Pcloud: %w", err) } updateTokenURL(oauthConfig, opt.Hostname) @@ -463,7 +463,7 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } for i := range result.Metadata.Contents { item := &result.Metadata.Contents[i] @@ -600,7 +600,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } f.dirCache.FlushDir(dir) if err != nil { @@ -872,7 +872,7 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "about failed") + return nil, fmt.Errorf("about failed: %w", err) } usage = &fs.Usage{ Total: fs.NewUsageValue(q.Quota), // quota of bytes that can be used @@ -952,7 +952,7 @@ func (o *Object) Hash(ctx context.Context, t hash.Type) (string, error) { if o.md5 == "" && o.sha1 == "" && o.sha256 == "" { err := o.getHashes(ctx) if err != nil { - return "", errors.Wrap(err, "failed to get hash") + return "", fmt.Errorf("failed to get hash: %w", err) } } return *pHash, nil @@ -971,7 +971,7 @@ func (o *Object) Size() int64 { // setMetaData sets the metadata from info func (o *Object) setMetaData(info *api.Item) (err error) { if info.IsFolder { - return errors.Wrapf(fs.ErrorNotAFile, "%q is a folder", o.remote) + return fmt.Errorf("%q is a folder: %w", o.remote, fs.ErrorNotAFile) } o.hasMetaData = true o.size = info.Size @@ -1058,7 +1058,7 @@ func (o *Object) downloadURL(ctx context.Context) (URL string, err error) { return "", err } if !result.IsValid() { - return "", errors.Errorf("fetched invalid link %+v", result) + return "", fmt.Errorf("fetched invalid link %+v", result) } o.link = &result return o.link.URL(), nil @@ -1146,7 +1146,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op if size == 0 { formReader, contentType, overhead, err := rest.MultipartUpload(ctx, in, opts.Parameters, "content", leaf) if err != nil { - return errors.Wrap(err, "failed to make multipart upload for 0 length file") + return fmt.Errorf("failed to make multipart upload for 0 length file: %w", err) } contentLength := overhead + size @@ -1177,7 +1177,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return err } if len(result.Items) != 1 { - return errors.Errorf("failed to upload %v - not sure why", o) + return fmt.Errorf("failed to upload %v - not sure why", o) } o.setHashes(&result.Checksums[0]) return o.setMetaData(&result.Items[0]) diff --git a/backend/premiumizeme/premiumizeme.go b/backend/premiumizeme/premiumizeme.go index 9f152a3f8..58e2898e1 100644 --- a/backend/premiumizeme/premiumizeme.go +++ b/backend/premiumizeme/premiumizeme.go @@ -18,6 +18,7 @@ canStream = false import ( "context" "encoding/json" + "errors" "fmt" "io" "net" @@ -27,7 +28,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/premiumizeme/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -250,7 +250,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.APIKey == "" { client, ts, err = oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure premiumize.me") + return nil, fmt.Errorf("failed to configure premiumize.me: %w", err) } } else { client = fshttp.NewClient(ctx) @@ -380,10 +380,10 @@ func (f *Fs) CreateDir(ctx context.Context, pathID, leaf string) (newID string, }) if err != nil { //fmt.Printf("...Error %v\n", err) - return "", errors.Wrap(err, "CreateDir http") + return "", fmt.Errorf("CreateDir http: %w", err) } if err = info.AsErr(); err != nil { - return "", errors.Wrap(err, "CreateDir") + return "", fmt.Errorf("CreateDir: %w", err) } // fmt.Printf("...Id %q\n", *info.Id) return info.ID, nil @@ -420,10 +420,10 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi return shouldRetry(ctx, resp, err) }) if err != nil { - return newDirID, found, errors.Wrap(err, "couldn't list files") + return newDirID, found, fmt.Errorf("couldn't list files: %w", err) } if err = result.AsErr(); err != nil { - return newDirID, found, errors.Wrap(err, "error while listing") + return newDirID, found, fmt.Errorf("error while listing: %w", err) } newDirID = result.FolderID for i := range result.Content { @@ -572,7 +572,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return true }) if err != nil { - return errors.Wrap(err, "purgeCheck") + return fmt.Errorf("purgeCheck: %w", err) } if found { return fs.ErrorDirectoryNotEmpty @@ -594,10 +594,10 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } if err = result.AsErr(); err != nil { - return errors.Wrap(err, "rmdir") + return fmt.Errorf("rmdir: %w", err) } f.dirCache.FlushDir(dir) if err != nil { @@ -645,7 +645,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir tmpLeaf := newLeaf + "." + random.String(8) err = f.renameLeaf(ctx, isFile, id, tmpLeaf) if err != nil { - return errors.Wrap(err, "Move rename leaf") + return fmt.Errorf("Move rename leaf: %w", err) } } @@ -674,10 +674,10 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "Move http") + return fmt.Errorf("Move http: %w", err) } if err = result.AsErr(); err != nil { - return errors.Wrap(err, "Move") + return fmt.Errorf("Move: %w", err) } } @@ -685,7 +685,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir if doRenameLeaf { err = f.renameLeaf(ctx, isFile, id, newLeaf) if err != nil { - return errors.Wrap(err, "Move rename leaf") + return fmt.Errorf("Move rename leaf: %w", err) } } @@ -783,10 +783,10 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "CreateDir http") + return nil, fmt.Errorf("CreateDir http: %w", err) } if err = info.AsErr(); err != nil { - return nil, errors.Wrap(err, "CreateDir") + return nil, fmt.Errorf("CreateDir: %w", err) } usage = &fs.Usage{ Used: fs.NewUsageValue(int64(info.SpaceUsed)), @@ -843,7 +843,7 @@ func (o *Object) Size() int64 { // setMetaData sets the metadata from info func (o *Object) setMetaData(info *api.Item) (err error) { if info.Type != "file" { - return errors.Wrapf(fs.ErrorNotAFile, "%q is %q", o.remote, info.Type) + return fmt.Errorf("%q is %q: %w", o.remote, info.Type, fs.ErrorNotAFile) } o.hasMetaData = true o.size = info.Size @@ -953,19 +953,19 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op var u *url.URL u, err = url.Parse(info.URL) if err != nil { - return true, errors.Wrap(err, "failed to parse download URL") + return true, fmt.Errorf("failed to parse download URL: %w", err) } _, err = net.LookupIP(u.Hostname()) if err != nil { - return true, errors.Wrap(err, "failed to resolve download URL") + return true, fmt.Errorf("failed to resolve download URL: %w", err) } return false, nil }) if err != nil { - return errors.Wrap(err, "upload get URL http") + return fmt.Errorf("upload get URL http: %w", err) } if err = info.AsErr(); err != nil { - return errors.Wrap(err, "upload get URL") + return fmt.Errorf("upload get URL: %w", err) } // if file exists then rename it out the way otherwise uploads can fail @@ -976,7 +976,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op fs.Debugf(o, "Moving old file out the way to %q", newLeaf) err = o.fs.renameLeaf(ctx, true, oldID, newLeaf) if err != nil { - return errors.Wrap(err, "upload rename old file") + return fmt.Errorf("upload rename old file: %w", err) } defer func() { // on failed upload rename old file back @@ -984,7 +984,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op fs.Debugf(o, "Renaming old file back (from %q to %q) since upload failed", leaf, newLeaf) newErr := o.fs.renameLeaf(ctx, true, oldID, leaf) if newErr != nil && err == nil { - err = errors.Wrap(newErr, "upload renaming old file back") + err = fmt.Errorf("upload renaming old file back: %w", newErr) } } }() @@ -1007,10 +1007,10 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "upload file http") + return fmt.Errorf("upload file http: %w", err) } if err = result.AsErr(); err != nil { - return errors.Wrap(err, "upload file") + return fmt.Errorf("upload file: %w", err) } // on successful upload, remove old file if it exists @@ -1019,7 +1019,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op fs.Debugf(o, "Removing old file") err := o.fs.remove(ctx, oldID) if err != nil { - return errors.Wrap(err, "upload remove old file") + return fmt.Errorf("upload remove old file: %w", err) } } @@ -1049,10 +1049,10 @@ func (f *Fs) renameLeaf(ctx context.Context, isFile bool, id string, newLeaf str return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "rename http") + return fmt.Errorf("rename http: %w", err) } if err = result.AsErr(); err != nil { - return errors.Wrap(err, "rename") + return fmt.Errorf("rename: %w", err) } return nil } @@ -1074,10 +1074,10 @@ func (f *Fs) remove(ctx context.Context, id string) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "remove http") + return fmt.Errorf("remove http: %w", err) } if err = result.AsErr(); err != nil { - return errors.Wrap(err, "remove") + return fmt.Errorf("remove: %w", err) } return nil } @@ -1086,7 +1086,7 @@ func (f *Fs) remove(ctx context.Context, id string) (err error) { func (o *Object) Remove(ctx context.Context) error { err := o.readMetaData(ctx) if err != nil { - return errors.Wrap(err, "Remove: Failed to read metadata") + return fmt.Errorf("Remove: Failed to read metadata: %w", err) } return o.fs.remove(ctx, o.id) } diff --git a/backend/putio/fs.go b/backend/putio/fs.go index fc8e352ac..073f86a44 100644 --- a/backend/putio/fs.go +++ b/backend/putio/fs.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "io" "net/http" @@ -13,7 +14,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/putdotio/go-putio/putio" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" @@ -80,7 +80,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (f fs.Fs, httpClient := fshttp.NewClient(ctx) oAuthClient, _, err := oauthutil.NewClientWithBaseClient(ctx, name, m, putioConfig, httpClient) if err != nil { - return nil, errors.Wrap(err, "failed to configure putio") + return nil, fmt.Errorf("failed to configure putio: %w", err) } p := &Fs{ name: name, @@ -469,7 +469,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) (err error) // check directory exists directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } dirID := atoi(directoryID) @@ -482,7 +482,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) (err error) return shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } if len(children) != 0 { return errors.New("directory not empty") @@ -647,7 +647,7 @@ func (f *Fs) About(ctx context.Context) (usage *fs.Usage, err error) { return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "about failed") + return nil, fmt.Errorf("about failed: %w", err) } return &fs.Usage{ Total: fs.NewUsageValue(ai.Disk.Size), // quota of bytes that can be used diff --git a/backend/putio/object.go b/backend/putio/object.go index acc988c58..0383a355e 100644 --- a/backend/putio/object.go +++ b/backend/putio/object.go @@ -2,6 +2,7 @@ package putio import ( "context" + "fmt" "io" "net/http" "net/url" @@ -9,7 +10,6 @@ import ( "strconv" "time" - "github.com/pkg/errors" "github.com/putdotio/go-putio/putio" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" @@ -82,7 +82,7 @@ func (o *Object) Hash(ctx context.Context, t hash.Type) (string, error) { } err := o.readEntryAndSetMetadata(ctx) if err != nil { - return "", errors.Wrap(err, "failed to read hash from metadata") + return "", fmt.Errorf("failed to read hash from metadata: %w", err) } return o.file.CRC32, nil } diff --git a/backend/qingstor/qingstor.go b/backend/qingstor/qingstor.go index da9581edc..d4053e250 100644 --- a/backend/qingstor/qingstor.go +++ b/backend/qingstor/qingstor.go @@ -8,6 +8,7 @@ package qingstor import ( "context" + "errors" "fmt" "io" "net/http" @@ -17,7 +18,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -285,7 +285,7 @@ func qsServiceConnection(ctx context.Context, opt *Options) (*qs.Service, error) func checkUploadChunkSize(cs fs.SizeSuffix) error { if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -300,7 +300,7 @@ func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) func checkUploadCutoff(cs fs.SizeSuffix) error { if cs > maxUploadCutoff { - return errors.Errorf("%s is greater than %s", cs, maxUploadCutoff) + return fmt.Errorf("%s is greater than %s", cs, maxUploadCutoff) } return nil } @@ -329,11 +329,11 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "qingstor: chunk size") + return nil, fmt.Errorf("qingstor: chunk size: %w", err) } err = checkUploadCutoff(opt.UploadCutoff) if err != nil { - return nil, errors.Wrap(err, "qingstor: upload cutoff") + return nil, fmt.Errorf("qingstor: upload cutoff: %w", err) } svc, err := qsServiceConnection(ctx, opt) if err != nil { @@ -884,7 +884,7 @@ func (f *Fs) cleanUpBucket(ctx context.Context, bucket string) (err error) { var resp *qs.ListMultipartUploadsOutput resp, err = bucketInit.ListMultipartUploads(&req) if err != nil { - return errors.Wrap(err, "clean up bucket list multipart uploads") + return fmt.Errorf("clean up bucket list multipart uploads: %w", err) } for _, upload := range resp.Uploads { if upload.Created != nil && upload.Key != nil && upload.UploadID != nil { @@ -896,7 +896,7 @@ func (f *Fs) cleanUpBucket(ctx context.Context, bucket string) (err error) { } _, abortErr := bucketInit.AbortMultipartUpload(*upload.Key, &req) if abortErr != nil { - err = errors.Wrapf(abortErr, "failed to remove multipart upload for %q", *upload.Key) + err = fmt.Errorf("failed to remove multipart upload for %q: %w", *upload.Key, abortErr) fs.Errorf(f, "%v", err) } } else { diff --git a/backend/qingstor/upload.go b/backend/qingstor/upload.go index 200ef3554..d9a818019 100644 --- a/backend/qingstor/upload.go +++ b/backend/qingstor/upload.go @@ -8,13 +8,13 @@ package qingstor import ( "bytes" "crypto/md5" + "errors" "fmt" "hash" "io" "sort" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/atexit" qs "github.com/yunify/qingstor-sdk-go/v3/service" @@ -175,7 +175,7 @@ func (u *uploader) upload() error { u.init() if u.cfg.partSize < minMultiPartSize { - return errors.Errorf("part size must be at least %d bytes", minMultiPartSize) + return fmt.Errorf("part size must be at least %d bytes", minMultiPartSize) } // Do one read to determine if we have more than one part @@ -184,7 +184,7 @@ func (u *uploader) upload() error { fs.Debugf(u, "Uploading as single part object to QingStor") return u.singlePartUpload(reader, u.readerPos) } else if err != nil { - return errors.Errorf("read upload data failed: %s", err) + return fmt.Errorf("read upload data failed: %s", err) } fs.Debugf(u, "Uploading as multi-part object to QingStor") diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 5fa7400f1..e01f6f2c4 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "encoding/hex" "encoding/xml" + "errors" "fmt" "io" "net/http" @@ -33,7 +34,6 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/ncw/swift/v2" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -1557,7 +1557,7 @@ func s3Connection(ctx context.Context, opt *Options, client *http.Client) (*s3.S // start a new AWS session awsSession, err := session.NewSession() if err != nil { - return nil, nil, errors.Wrap(err, "NewSession") + return nil, nil, fmt.Errorf("NewSession: %w", err) } // first provider to supply a credential set "wins" @@ -1661,7 +1661,7 @@ func s3Connection(ctx context.Context, opt *Options, client *http.Client) (*s3.S func checkUploadChunkSize(cs fs.SizeSuffix) error { if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -1676,7 +1676,7 @@ func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) func checkUploadCutoff(cs fs.SizeSuffix) error { if cs > maxUploadCutoff { - return errors.Errorf("%s is greater than %s", cs, maxUploadCutoff) + return fmt.Errorf("%s is greater than %s", cs, maxUploadCutoff) } return nil } @@ -1789,11 +1789,11 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "s3: chunk size") + return nil, fmt.Errorf("s3: chunk size: %w", err) } err = checkUploadCutoff(opt.UploadCutoff) if err != nil { - return nil, errors.Wrap(err, "s3: upload cutoff") + return nil, fmt.Errorf("s3: upload cutoff: %w", err) } if opt.ACL == "" { opt.ACL = "private" @@ -1931,13 +1931,13 @@ func (f *Fs) getBucketLocation(ctx context.Context, bucket string) (string, erro func (f *Fs) updateRegionForBucket(ctx context.Context, bucket string) error { region, err := f.getBucketLocation(ctx, bucket) if err != nil { - return errors.Wrap(err, "reading bucket location failed") + return fmt.Errorf("reading bucket location failed: %w", err) } if aws.StringValue(f.c.Config.Endpoint) != "" { - return errors.Errorf("can't set region to %q as endpoint is set", region) + return fmt.Errorf("can't set region to %q as endpoint is set", region) } if aws.StringValue(f.c.Config.Region) == region { - return errors.Errorf("region is already %q - not updating", region) + return fmt.Errorf("region is already %q - not updating", region) } // Make a new session with the new region @@ -1945,7 +1945,7 @@ func (f *Fs) updateRegionForBucket(ctx context.Context, bucket string) error { f.opt.Region = region c, ses, err := s3Connection(f.ctx, &f.opt, f.srv) if err != nil { - return errors.Wrap(err, "creating new session failed") + return fmt.Errorf("creating new session failed: %w", err) } f.c = c f.ses = ses @@ -2141,7 +2141,7 @@ func (f *Fs) list(ctx context.Context, bucket, directory, prefix string, addBuck if startAfter != nil && urlEncodeListings { *startAfter, err = url.QueryUnescape(*startAfter) if err != nil { - return errors.Wrapf(err, "failed to URL decode StartAfter/NextMarker %q", *continuationToken) + return fmt.Errorf("failed to URL decode StartAfter/NextMarker %q: %w", *continuationToken, err) } } } @@ -2727,7 +2727,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str if lifetime := opt["lifetime"]; lifetime != "" { ilifetime, err := strconv.ParseInt(lifetime, 10, 64) if err != nil { - return nil, errors.Wrap(err, "bad lifetime") + return nil, fmt.Errorf("bad lifetime: %w", err) } req.RestoreRequest.Days = &ilifetime } @@ -2786,7 +2786,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str if opt["max-age"] != "" { maxAge, err = fs.ParseDuration(opt["max-age"]) if err != nil { - return nil, errors.Wrap(err, "bad max-age") + return nil, fmt.Errorf("bad max-age: %w", err) } } return nil, f.cleanUp(ctx, maxAge) @@ -2820,7 +2820,7 @@ func (f *Fs) listMultipartUploads(ctx context.Context, bucket, key string) (uplo return f.shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrapf(err, "list multipart uploads bucket %q key %q", bucket, key) + return nil, fmt.Errorf("list multipart uploads bucket %q key %q: %w", bucket, key, err) } uploads = append(uploads, resp.Uploads...) if !aws.BoolValue(resp.IsTruncated) { @@ -2878,7 +2878,7 @@ func (f *Fs) cleanUpBucket(ctx context.Context, bucket string, maxAge time.Durat } _, abortErr := f.c.AbortMultipartUpload(&req) if abortErr != nil { - err = errors.Wrapf(abortErr, "failed to remove %s", what) + err = fmt.Errorf("failed to remove %s: %w", what, abortErr) fs.Errorf(f, "%v", err) } } else { @@ -3218,7 +3218,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read }) if err, ok := err.(awserr.RequestFailure); ok { if err.Code() == "InvalidObjectState" { - return nil, errors.Errorf("Object in GLACIER, restore first: bucket=%q, key=%q", bucket, bucketPath) + return nil, fmt.Errorf("Object in GLACIER, restore first: bucket=%q, key=%q", bucket, bucketPath) } } if err != nil { @@ -3296,7 +3296,7 @@ func (o *Object) uploadMultipart(ctx context.Context, req *s3.PutObjectInput, si return f.shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "multipart upload failed to initialise") + return fmt.Errorf("multipart upload failed to initialise: %w", err) } uid := cout.UploadId @@ -3356,7 +3356,7 @@ func (o *Object) uploadMultipart(ctx context.Context, req *s3.PutObjectInput, si finished = true } else if err != nil { free() - return errors.Wrap(err, "multipart upload failed to read source") + return fmt.Errorf("multipart upload failed to read source: %w", err) } buf = buf[:n] @@ -3403,7 +3403,7 @@ func (o *Object) uploadMultipart(ctx context.Context, req *s3.PutObjectInput, si return false, nil }) if err != nil { - return errors.Wrap(err, "multipart upload failed to upload part") + return fmt.Errorf("multipart upload failed to upload part: %w", err) } return nil }) @@ -3431,7 +3431,7 @@ func (o *Object) uploadMultipart(ctx context.Context, req *s3.PutObjectInput, si return f.shouldRetry(ctx, err) }) if err != nil { - return errors.Wrap(err, "multipart upload failed to finalise") + return fmt.Errorf("multipart upload failed to finalise: %w", err) } return nil } @@ -3557,7 +3557,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // PutObject so we'll use this work-around. url, headers, err := putObj.PresignRequest(15 * time.Minute) if err != nil { - return errors.Wrap(err, "s3 upload: sign request") + return fmt.Errorf("s3 upload: sign request: %w", err) } if o.fs.opt.V2Auth && headers == nil { @@ -3572,7 +3572,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // create the vanilla http request httpReq, err := http.NewRequestWithContext(ctx, "PUT", url, in) if err != nil { - return errors.Wrap(err, "s3 upload: new request") + return fmt.Errorf("s3 upload: new request: %w", err) } // set the headers we signed and the length @@ -3592,7 +3592,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op if resp.StatusCode >= 200 && resp.StatusCode < 299 { return false, nil } - err = errors.Errorf("s3 upload: %s: %s", resp.Status, body) + err = fmt.Errorf("s3 upload: %s: %s", resp.Status, body) return fserrors.ShouldRetryHTTP(resp, retryErrorCodes), err }) if err != nil { diff --git a/backend/seafile/seafile.go b/backend/seafile/seafile.go index e6100ab00..76f9843ab 100644 --- a/backend/seafile/seafile.go +++ b/backend/seafile/seafile.go @@ -2,6 +2,7 @@ package seafile import ( "context" + "errors" "fmt" "io" "net/http" @@ -13,7 +14,6 @@ import ( "time" "github.com/coreos/go-semver/semver" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/seafile/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -171,14 +171,14 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e var err error opt.Password, err = obscure.Reveal(opt.Password) if err != nil { - return nil, errors.Wrap(err, "couldn't decrypt user password") + return nil, fmt.Errorf("couldn't decrypt user password: %w", err) } } if opt.LibraryKey != "" { var err error opt.LibraryKey, err = obscure.Reveal(opt.LibraryKey) if err != nil { - return nil, errors.Wrap(err, "couldn't decrypt library password") + return nil, fmt.Errorf("couldn't decrypt library password: %w", err) } } @@ -282,7 +282,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } _, err := f.NewObject(ctx, remote) if err != nil { - if errors.Cause(err) == fs.ErrorObjectNotFound || errors.Cause(err) == fs.ErrorNotAFile { + if errors.Is(err, fs.ErrorObjectNotFound) || errors.Is(err, fs.ErrorNotAFile) { // File doesn't exist so return the original f f.rootDirectory = rootDirectory return f, nil @@ -305,7 +305,7 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf u, err := url.Parse(serverURL) if err != nil { - return nil, errors.Errorf("invalid server URL %s", serverURL) + return nil, fmt.Errorf("invalid server URL %s", serverURL) } is2faEnabled, _ := m.Get(config2FA) @@ -886,7 +886,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string // 1- rename source err = srcFs.renameDir(ctx, srcLibraryID, srcPath, tempName) if err != nil { - return errors.Wrap(err, "Cannot rename source directory to a temporary name") + return fmt.Errorf("Cannot rename source directory to a temporary name: %w", err) } // 2- move source to destination @@ -900,7 +900,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string // 3- rename destination back to source name err = f.renameDir(ctx, dstLibraryID, path.Join(dstDir, tempName), dstName) if err != nil { - return errors.Wrap(err, "Cannot rename temporary directory to destination name") + return fmt.Errorf("Cannot rename temporary directory to destination name: %w", err) } return nil diff --git a/backend/seafile/webapi.go b/backend/seafile/webapi.go index 563cd1896..29d2f8645 100644 --- a/backend/seafile/webapi.go +++ b/backend/seafile/webapi.go @@ -3,6 +3,7 @@ package seafile import ( "bytes" "context" + "errors" "fmt" "io" "io/ioutil" @@ -11,7 +12,6 @@ import ( "path" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/seafile/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/readers" @@ -61,7 +61,7 @@ func getAuthorizationToken(ctx context.Context, srv *rest.Client, user, password _, err := srv.CallJSON(ctx, &opts, &request, &result) if err != nil { // This is only going to be http errors here - return "", errors.Wrap(err, "failed to authenticate") + return "", fmt.Errorf("failed to authenticate: %w", err) } if result.Errors != nil && len(result.Errors) > 0 { return "", errors.New(strings.Join(result.Errors, ", ")) @@ -94,7 +94,7 @@ func (f *Fs) getServerInfo(ctx context.Context) (account *api.ServerInfo, err er return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get server info") + return nil, fmt.Errorf("failed to get server info: %w", err) } return &result, nil } @@ -120,7 +120,7 @@ func (f *Fs) getUserAccountInfo(ctx context.Context) (account *api.AccountInfo, return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get account info") + return nil, fmt.Errorf("failed to get account info: %w", err) } return &result, nil } @@ -147,7 +147,7 @@ func (f *Fs) getLibraries(ctx context.Context) ([]api.Library, error) { return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get libraries") + return nil, fmt.Errorf("failed to get libraries: %w", err) } return result, nil } @@ -178,7 +178,7 @@ func (f *Fs) createLibrary(ctx context.Context, libraryName, password string) (l return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to create library") + return nil, fmt.Errorf("failed to create library: %w", err) } return result, nil } @@ -205,7 +205,7 @@ func (f *Fs) deleteLibrary(ctx context.Context, libraryID string) error { return fs.ErrorPermissionDenied } } - return errors.Wrap(err, "failed to delete library") + return fmt.Errorf("failed to delete library: %w", err) } return nil } @@ -240,7 +240,7 @@ func (f *Fs) decryptLibrary(ctx context.Context, libraryID, password string) err return nil } } - return errors.Wrap(err, "failed to decrypt library") + return fmt.Errorf("failed to decrypt library: %w", err) } return nil } @@ -286,7 +286,7 @@ func (f *Fs) getDirectoryEntriesAPIv21(ctx context.Context, libraryID, dirPath s return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get directory contents") + return nil, fmt.Errorf("failed to get directory contents: %w", err) } // Clean up encoded names @@ -327,7 +327,7 @@ func (f *Fs) getDirectoryDetails(ctx context.Context, libraryID, dirPath string) return nil, fs.ErrorDirNotFound } } - return nil, errors.Wrap(err, "failed to get directory details") + return nil, fmt.Errorf("failed to get directory details: %w", err) } result.Name = f.opt.Enc.ToStandardName(result.Name) result.Path = f.opt.Enc.ToStandardPath(result.Path) @@ -366,7 +366,7 @@ func (f *Fs) createDir(ctx context.Context, libraryID, dirPath string) error { return fs.ErrorPermissionDenied } } - return errors.Wrap(err, "failed to create directory") + return fmt.Errorf("failed to create directory: %w", err) } return nil } @@ -406,7 +406,7 @@ func (f *Fs) renameDir(ctx context.Context, libraryID, dirPath, newName string) return fs.ErrorPermissionDenied } } - return errors.Wrap(err, "failed to rename directory") + return fmt.Errorf("failed to rename directory: %w", err) } return nil } @@ -449,7 +449,7 @@ func (f *Fs) moveDir(ctx context.Context, srcLibraryID, srcDir, srcName, dstLibr return fs.ErrorObjectNotFound } } - return errors.Wrap(err, fmt.Sprintf("failed to move directory '%s' from '%s' to '%s'", srcName, srcDir, dstPath)) + return fmt.Errorf("failed to move directory '%s' from '%s' to '%s': %w", srcName, srcDir, dstPath, err) } return nil @@ -482,7 +482,7 @@ func (f *Fs) deleteDir(ctx context.Context, libraryID, filePath string) error { return fs.ErrorPermissionDenied } } - return errors.Wrap(err, "failed to delete directory") + return fmt.Errorf("failed to delete directory: %w", err) } return nil } @@ -516,7 +516,7 @@ func (f *Fs) getFileDetails(ctx context.Context, libraryID, filePath string) (*a return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get file details") + return nil, fmt.Errorf("failed to get file details: %w", err) } result.Name = f.opt.Enc.ToStandardName(result.Name) result.Parent = f.opt.Enc.ToStandardPath(result.Parent) @@ -542,7 +542,7 @@ func (f *Fs) deleteFile(ctx context.Context, libraryID, filePath string) error { return f.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to delete file") + return fmt.Errorf("failed to delete file: %w", err) } return nil } @@ -573,7 +573,7 @@ func (f *Fs) getDownloadLink(ctx context.Context, libraryID, filePath string) (s return "", fs.ErrorObjectNotFound } } - return "", errors.Wrap(err, "failed to get download link") + return "", fmt.Errorf("failed to get download link: %w", err) } return result, nil } @@ -667,7 +667,7 @@ func (f *Fs) getUploadLink(ctx context.Context, libraryID string) (string, error return "", fs.ErrorPermissionDenied } } - return "", errors.Wrap(err, "failed to get upload link") + return "", fmt.Errorf("failed to get upload link: %w", err) } return result, nil } @@ -684,7 +684,7 @@ func (f *Fs) upload(ctx context.Context, in io.Reader, uploadLink, filePath stri } formReader, contentType, _, err := rest.MultipartUpload(ctx, in, parameters, "file", f.opt.Enc.FromStandardName(filename)) if err != nil { - return nil, errors.Wrap(err, "failed to make multipart upload") + return nil, fmt.Errorf("failed to make multipart upload: %w", err) } opts := rest.Opts{ @@ -711,7 +711,7 @@ func (f *Fs) upload(ctx context.Context, in io.Reader, uploadLink, filePath stri return nil, ErrorInternalDuringUpload } } - return nil, errors.Wrap(err, "failed to upload file") + return nil, fmt.Errorf("failed to upload file: %w", err) } if len(result) > 0 { result[0].Parent = f.opt.Enc.ToStandardPath(result[0].Parent) @@ -750,7 +750,7 @@ func (f *Fs) listShareLinks(ctx context.Context, libraryID, remote string) ([]ap return nil, fs.ErrorObjectNotFound } } - return nil, errors.Wrap(err, "failed to list shared links") + return nil, fmt.Errorf("failed to list shared links: %w", err) } return result, nil } @@ -788,7 +788,7 @@ func (f *Fs) createShareLink(ctx context.Context, libraryID, remote string) (*ap return nil, fs.ErrorObjectNotFound } } - return nil, errors.Wrap(err, "failed to create a shared link") + return nil, fmt.Errorf("failed to create a shared link: %w", err) } return result, nil } @@ -830,7 +830,7 @@ func (f *Fs) copyFile(ctx context.Context, srcLibraryID, srcPath, dstLibraryID, return nil, fs.ErrorObjectNotFound } } - return nil, errors.Wrap(err, fmt.Sprintf("failed to copy file %s:'%s' to %s:'%s'", srcLibraryID, srcPath, dstLibraryID, dstPath)) + return nil, fmt.Errorf("failed to copy file %s:'%s' to %s:'%s': %w", srcLibraryID, srcPath, dstLibraryID, dstPath, err) } return f.decodeFileInfo(result), nil } @@ -872,7 +872,7 @@ func (f *Fs) moveFile(ctx context.Context, srcLibraryID, srcPath, dstLibraryID, return nil, fs.ErrorObjectNotFound } } - return nil, errors.Wrap(err, fmt.Sprintf("failed to move file %s:'%s' to %s:'%s'", srcLibraryID, srcPath, dstLibraryID, dstPath)) + return nil, fmt.Errorf("failed to move file %s:'%s' to %s:'%s': %w", srcLibraryID, srcPath, dstLibraryID, dstPath, err) } return f.decodeFileInfo(result), nil } @@ -912,7 +912,7 @@ func (f *Fs) renameFile(ctx context.Context, libraryID, filePath, newname string return nil, fs.ErrorObjectNotFound } } - return nil, errors.Wrap(err, fmt.Sprintf("failed to rename file '%s' to '%s'", filePath, newname)) + return nil, fmt.Errorf("failed to rename file '%s' to '%s': %w", filePath, newname, err) } return f.decodeFileInfo(result), nil } @@ -949,7 +949,7 @@ func (f *Fs) emptyLibraryTrash(ctx context.Context, libraryID string) error { return fs.ErrorObjectNotFound } } - return errors.Wrap(err, "failed empty the library trash") + return fmt.Errorf("failed empty the library trash: %w", err) } return nil } @@ -991,7 +991,7 @@ func (f *Fs) getDirectoryEntriesAPIv2(ctx context.Context, libraryID, dirPath st return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, "failed to get directory contents") + return nil, fmt.Errorf("failed to get directory contents: %w", err) } // Clean up encoded names @@ -1038,7 +1038,7 @@ func (f *Fs) copyFileAPIv2(ctx context.Context, srcLibraryID, srcPath, dstLibrar return nil, fs.ErrorPermissionDenied } } - return nil, errors.Wrap(err, fmt.Sprintf("failed to copy file %s:'%s' to %s:'%s'", srcLibraryID, srcPath, dstLibraryID, dstPath)) + return nil, fmt.Errorf("failed to copy file %s:'%s' to %s:'%s': %w", srcLibraryID, srcPath, dstLibraryID, dstPath, err) } err = rest.DecodeJSON(resp, &result) if err != nil { @@ -1090,7 +1090,7 @@ func (f *Fs) renameFileAPIv2(ctx context.Context, libraryID, filePath, newname s return fs.ErrorObjectNotFound } } - return errors.Wrap(err, "failed to rename file") + return fmt.Errorf("failed to rename file: %w", err) } return nil } diff --git a/backend/sftp/sftp.go b/backend/sftp/sftp.go index 1564ff90c..86a452315 100644 --- a/backend/sftp/sftp.go +++ b/backend/sftp/sftp.go @@ -8,6 +8,7 @@ package sftp import ( "bytes" "context" + "errors" "fmt" "io" "io/ioutil" @@ -20,7 +21,6 @@ import ( "sync/atomic" "time" - "github.com/pkg/errors" "github.com/pkg/sftp" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -384,12 +384,12 @@ func (f *Fs) sftpConnection(ctx context.Context) (c *conn, err error) { } c.sshClient, err = f.dial(ctx, "tcp", f.opt.Host+":"+f.opt.Port, f.config) if err != nil { - return nil, errors.Wrap(err, "couldn't connect SSH") + return nil, fmt.Errorf("couldn't connect SSH: %w", err) } c.sftpClient, err = f.newSftpClient(c.sshClient) if err != nil { _ = c.sshClient.Close() - return nil, errors.Wrap(err, "couldn't initialise SFTP") + return nil, fmt.Errorf("couldn't initialise SFTP: %w", err) } go c.wait() return c, nil @@ -468,16 +468,16 @@ func (f *Fs) putSftpConnection(pc **conn, err error) { *pc = nil if err != nil { // work out if this is an expected error - underlyingErr := errors.Cause(err) isRegularError := false - switch underlyingErr { - case os.ErrNotExist: + var statusErr *sftp.StatusError + var pathErr *os.PathError + switch { + case errors.Is(err, os.ErrNotExist): + isRegularError = true + case errors.As(err, &statusErr): + isRegularError = true + case errors.As(err, &pathErr): isRegularError = true - default: - switch underlyingErr.(type) { - case *sftp.StatusError, *os.PathError: - isRegularError = true - } } // If not a regular SFTP error code then check the connection if !isRegularError { @@ -561,7 +561,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.KnownHostsFile != "" { hostcallback, err := knownhosts.New(env.ShellExpand(opt.KnownHostsFile)) if err != nil { - return nil, errors.Wrap(err, "couldn't parse known_hosts_file") + return nil, fmt.Errorf("couldn't parse known_hosts_file: %w", err) } sshConfig.HostKeyCallback = hostcallback } @@ -579,20 +579,20 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if (opt.Pass == "" && keyFile == "" && !opt.AskPassword && opt.KeyPem == "") || opt.KeyUseAgent { sshAgentClient, _, err := sshagent.New() if err != nil { - return nil, errors.Wrap(err, "couldn't connect to ssh-agent") + return nil, fmt.Errorf("couldn't connect to ssh-agent: %w", err) } signers, err := sshAgentClient.Signers() if err != nil { - return nil, errors.Wrap(err, "couldn't read ssh agent signers") + return nil, fmt.Errorf("couldn't read ssh agent signers: %w", err) } if keyFile != "" { pubBytes, err := ioutil.ReadFile(keyFile + ".pub") if err != nil { - return nil, errors.Wrap(err, "failed to read public key file") + return nil, fmt.Errorf("failed to read public key file: %w", err) } pub, _, _, _, err := ssh.ParseAuthorizedKey(pubBytes) if err != nil { - return nil, errors.Wrap(err, "failed to parse public key file") + return nil, fmt.Errorf("failed to parse public key file: %w", err) } pubM := pub.Marshal() found := false @@ -617,13 +617,13 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.KeyPem == "" { key, err = ioutil.ReadFile(keyFile) if err != nil { - return nil, errors.Wrap(err, "failed to read private key file") + return nil, fmt.Errorf("failed to read private key file: %w", err) } } else { // wrap in quotes because the config is a coming as a literal without them. opt.KeyPem, err = strconv.Unquote("\"" + opt.KeyPem + "\"") if err != nil { - return nil, errors.Wrap(err, "pem key not formatted properly") + return nil, fmt.Errorf("pem key not formatted properly: %w", err) } key = []byte(opt.KeyPem) } @@ -641,19 +641,19 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(clearpass)) } if err != nil { - return nil, errors.Wrap(err, "failed to parse private key file") + return nil, fmt.Errorf("failed to parse private key file: %w", err) } // If a public key has been specified then use that if pubkeyFile != "" { certfile, err := ioutil.ReadFile(pubkeyFile) if err != nil { - return nil, errors.Wrap(err, "unable to read cert file") + return nil, fmt.Errorf("unable to read cert file: %w", err) } pk, _, _, _, err := ssh.ParseAuthorizedKey(certfile) if err != nil { - return nil, errors.Wrap(err, "unable to parse cert file") + return nil, fmt.Errorf("unable to parse cert file: %w", err) } // And the signer for this, which includes the private key signer @@ -669,7 +669,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } pubsigner, err := ssh.NewCertSigner(cert, signer) if err != nil { - return nil, errors.Wrap(err, "error generating cert signer") + return nil, fmt.Errorf("error generating cert signer: %w", err) } sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeys(pubsigner)) } else { @@ -759,7 +759,7 @@ func NewFsWithConnection(ctx context.Context, f *Fs, name string, root string, m // Make a connection and pool it to return errors early c, err := f.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "NewFs") + return nil, fmt.Errorf("NewFs: %w", err) } cwd, err := c.sftpClient.Getwd() f.putSftpConnection(&c, nil) @@ -840,7 +840,7 @@ func (f *Fs) dirExists(ctx context.Context, dir string) (bool, error) { } c, err := f.getSftpConnection(ctx) if err != nil { - return false, errors.Wrap(err, "dirExists") + return false, fmt.Errorf("dirExists: %w", err) } info, err := c.sftpClient.Stat(dir) f.putSftpConnection(&c, err) @@ -848,7 +848,7 @@ func (f *Fs) dirExists(ctx context.Context, dir string) (bool, error) { if os.IsNotExist(err) { return false, nil } - return false, errors.Wrap(err, "dirExists stat failed") + return false, fmt.Errorf("dirExists stat failed: %w", err) } if !info.IsDir() { return false, fs.ErrorIsFile @@ -869,7 +869,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e root := path.Join(f.absRoot, dir) ok, err := f.dirExists(ctx, root) if err != nil { - return nil, errors.Wrap(err, "List failed") + return nil, fmt.Errorf("List failed: %w", err) } if !ok { return nil, fs.ErrorDirNotFound @@ -880,12 +880,12 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e } c, err := f.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "List") + return nil, fmt.Errorf("List: %w", err) } infos, err := c.sftpClient.ReadDir(sftpDir) f.putSftpConnection(&c, err) if err != nil { - return nil, errors.Wrapf(err, "error listing %q", dir) + return nil, fmt.Errorf("error listing %q: %w", dir, err) } for _, info := range infos { remote := path.Join(dir, info.Name()) @@ -924,7 +924,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) { err := f.mkParentDir(ctx, src.Remote()) if err != nil { - return nil, errors.Wrap(err, "Put mkParentDir failed") + return nil, fmt.Errorf("Put mkParentDir failed: %w", err) } // Temporary object under construction o := &Object{ @@ -959,7 +959,7 @@ func (f *Fs) mkdir(ctx context.Context, dirPath string) error { } ok, err := f.dirExists(ctx, dirPath) if err != nil { - return errors.Wrap(err, "mkdir dirExists failed") + return fmt.Errorf("mkdir dirExists failed: %w", err) } if ok { return nil @@ -971,12 +971,12 @@ func (f *Fs) mkdir(ctx context.Context, dirPath string) error { } c, err := f.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "mkdir") + return fmt.Errorf("mkdir: %w", err) } err = c.sftpClient.Mkdir(dirPath) f.putSftpConnection(&c, err) if err != nil { - return errors.Wrapf(err, "mkdir %q failed", dirPath) + return fmt.Errorf("mkdir %q failed: %w", dirPath, err) } return nil } @@ -993,7 +993,7 @@ func (f *Fs) Rmdir(ctx context.Context, dir string) error { // delete recursively with RemoveDirectory entries, err := f.List(ctx, dir) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } if len(entries) != 0 { return fs.ErrorDirectoryNotEmpty @@ -1002,7 +1002,7 @@ func (f *Fs) Rmdir(ctx context.Context, dir string) error { root := path.Join(f.absRoot, dir) c, err := f.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "Rmdir") + return fmt.Errorf("Rmdir: %w", err) } err = c.sftpClient.RemoveDirectory(root) f.putSftpConnection(&c, err) @@ -1018,11 +1018,11 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } err := f.mkParentDir(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "Move mkParentDir failed") + return nil, fmt.Errorf("Move mkParentDir failed: %w", err) } c, err := f.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "Move") + return nil, fmt.Errorf("Move: %w", err) } err = c.sftpClient.Rename( srcObj.path(), @@ -1030,11 +1030,11 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, ) f.putSftpConnection(&c, err) if err != nil { - return nil, errors.Wrap(err, "Move Rename failed") + return nil, fmt.Errorf("Move Rename failed: %w", err) } dstObj, err := f.NewObject(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "Move NewObject failed") + return nil, fmt.Errorf("Move NewObject failed: %w", err) } return dstObj, nil } @@ -1059,7 +1059,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string // Check if destination exists ok, err := f.dirExists(ctx, dstPath) if err != nil { - return errors.Wrap(err, "DirMove dirExists dst failed") + return fmt.Errorf("DirMove dirExists dst failed: %w", err) } if ok { return fs.ErrorDirExists @@ -1068,13 +1068,13 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string // Make sure the parent directory exists err = f.mkdir(ctx, path.Dir(dstPath)) if err != nil { - return errors.Wrap(err, "DirMove mkParentDir dst failed") + return fmt.Errorf("DirMove mkParentDir dst failed: %w", err) } // Do the move c, err := f.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "DirMove") + return fmt.Errorf("DirMove: %w", err) } err = c.sftpClient.Rename( srcPath, @@ -1082,7 +1082,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string ) f.putSftpConnection(&c, err) if err != nil { - return errors.Wrapf(err, "DirMove Rename(%q,%q) failed", srcPath, dstPath) + return fmt.Errorf("DirMove Rename(%q,%q) failed: %w", srcPath, dstPath, err) } return nil } @@ -1094,13 +1094,13 @@ func (f *Fs) run(ctx context.Context, cmd string) ([]byte, error) { c, err := f.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "run: get SFTP connection") + return nil, fmt.Errorf("run: get SFTP connection: %w", err) } defer f.putSftpConnection(&c, err) session, err := c.sshClient.NewSession() if err != nil { - return nil, errors.Wrap(err, "run: get SFTP session") + return nil, fmt.Errorf("run: get SFTP session: %w", err) } defer func() { _ = session.Close() @@ -1112,7 +1112,7 @@ func (f *Fs) run(ctx context.Context, cmd string) ([]byte, error) { err = session.Run(cmd) if err != nil { - return nil, errors.Wrapf(err, "failed to run %q: %s", cmd, stderr.Bytes()) + return nil, fmt.Errorf("failed to run %q: %s: %w", cmd, stderr.Bytes(), err) } return stdout.Bytes(), nil @@ -1186,7 +1186,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { } stdout, err := f.run(ctx, "df -k "+escapedPath) if err != nil { - return nil, errors.Wrap(err, "your remote may not support About") + return nil, fmt.Errorf("your remote may not support About: %w", err) } usageTotal, usageUsed, usageAvail := parseUsage(stdout) @@ -1257,12 +1257,12 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) { c, err := o.fs.getSftpConnection(ctx) if err != nil { - return "", errors.Wrap(err, "Hash get SFTP connection") + return "", fmt.Errorf("Hash get SFTP connection: %w", err) } session, err := c.sshClient.NewSession() o.fs.putSftpConnection(&c, err) if err != nil { - return "", errors.Wrap(err, "Hash put SFTP connection") + return "", fmt.Errorf("Hash put SFTP connection: %w", err) } var stdout, stderr bytes.Buffer @@ -1366,7 +1366,7 @@ func (o *Object) setMetadata(info os.FileInfo) { func (f *Fs) stat(ctx context.Context, remote string) (info os.FileInfo, err error) { c, err := f.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "stat") + return nil, fmt.Errorf("stat: %w", err) } absPath := path.Join(f.absRoot, remote) info, err = c.sftpClient.Stat(absPath) @@ -1381,7 +1381,7 @@ func (o *Object) stat(ctx context.Context) error { if os.IsNotExist(err) { return fs.ErrorObjectNotFound } - return errors.Wrap(err, "stat failed") + return fmt.Errorf("stat failed: %w", err) } if info.IsDir() { return fs.ErrorIsDir @@ -1399,16 +1399,16 @@ func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error { } c, err := o.fs.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "SetModTime") + return fmt.Errorf("SetModTime: %w", err) } err = c.sftpClient.Chtimes(o.path(), modTime, modTime) o.fs.putSftpConnection(&c, err) if err != nil { - return errors.Wrap(err, "SetModTime failed") + return fmt.Errorf("SetModTime failed: %w", err) } err = o.stat(ctx) if err != nil { - return errors.Wrap(err, "SetModTime stat failed") + return fmt.Errorf("SetModTime stat failed: %w", err) } return nil } @@ -1487,17 +1487,17 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read } c, err := o.fs.getSftpConnection(ctx) if err != nil { - return nil, errors.Wrap(err, "Open") + return nil, fmt.Errorf("Open: %w", err) } sftpFile, err := c.sftpClient.Open(o.path()) o.fs.putSftpConnection(&c, err) if err != nil { - return nil, errors.Wrap(err, "Open failed") + return nil, fmt.Errorf("Open failed: %w", err) } if offset > 0 { off, err := sftpFile.Seek(offset, io.SeekStart) if err != nil || off != offset { - return nil, errors.Wrap(err, "Open Seek failed") + return nil, fmt.Errorf("Open Seek failed: %w", err) } } in = readers.NewLimitedReadCloser(o.fs.newObjectReader(sftpFile), limit) @@ -1526,12 +1526,12 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op o.sha1sum = nil c, err := o.fs.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "Update") + return fmt.Errorf("Update: %w", err) } file, err := c.sftpClient.OpenFile(o.path(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC) o.fs.putSftpConnection(&c, err) if err != nil { - return errors.Wrap(err, "Update Create failed") + return fmt.Errorf("Update Create failed: %w", err) } // remove the file if upload failed remove := func() { @@ -1551,18 +1551,18 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op _, err = file.ReadFrom(&sizeReader{Reader: in, size: src.Size()}) if err != nil { remove() - return errors.Wrap(err, "Update ReadFrom failed") + return fmt.Errorf("Update ReadFrom failed: %w", err) } err = file.Close() if err != nil { remove() - return errors.Wrap(err, "Update Close failed") + return fmt.Errorf("Update Close failed: %w", err) } // Set the mod time - this stats the object if o.fs.opt.SetModTime == true err = o.SetModTime(ctx, src.ModTime(ctx)) if err != nil { - return errors.Wrap(err, "Update SetModTime failed") + return fmt.Errorf("Update SetModTime failed: %w", err) } // Stat the file after the upload to read its stats back if o.fs.opt.SetModTime == false @@ -1576,7 +1576,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op o.size = src.Size() o.mode = os.FileMode(0666) // regular file } else if err != nil { - return errors.Wrap(err, "Update stat failed") + return fmt.Errorf("Update stat failed: %w", err) } } @@ -1587,7 +1587,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op func (o *Object) Remove(ctx context.Context) error { c, err := o.fs.getSftpConnection(ctx) if err != nil { - return errors.Wrap(err, "Remove") + return fmt.Errorf("Remove: %w", err) } err = c.sftpClient.Remove(o.path()) o.fs.putSftpConnection(&c, err) diff --git a/backend/sharefile/api/types.go b/backend/sharefile/api/types.go index 655681351..7b48bbec7 100644 --- a/backend/sharefile/api/types.go +++ b/backend/sharefile/api/types.go @@ -2,10 +2,9 @@ package api import ( + "errors" "fmt" "time" - - "github.com/pkg/errors" ) // ListRequestSelect should be used in $select for Items/Children @@ -122,7 +121,7 @@ type UploadFinishResponse struct { // ID returns the ID of the first response if available func (finish *UploadFinishResponse) ID() (string, error) { if finish.Error { - return "", errors.Errorf("upload failed: %s (%d)", finish.ErrorMessage, finish.ErrorCode) + return "", fmt.Errorf("upload failed: %s (%d)", finish.ErrorMessage, finish.ErrorCode) } if len(finish.Value) == 0 { return "", errors.New("upload failed: no results returned") diff --git a/backend/sharefile/sharefile.go b/backend/sharefile/sharefile.go index 62378d9f3..69da61cb9 100644 --- a/backend/sharefile/sharefile.go +++ b/backend/sharefile/sharefile.go @@ -74,6 +74,7 @@ Which is control chars + [' ', '*', '.', '/', ':', '<', '>', '?', '|'] import ( "context" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -83,7 +84,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/sharefile/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -144,7 +144,7 @@ func init() { subdomain := auth.Form.Get("subdomain") apicp := auth.Form.Get("apicp") if subdomain == "" || apicp == "" { - return errors.Errorf("subdomain or apicp not found in response: %+v", auth.Form) + return fmt.Errorf("subdomain or apicp not found in response: %+v", auth.Form) } endpoint := "https://" + subdomain + "." + apicp m.Set("endpoint", endpoint) @@ -334,7 +334,7 @@ func (f *Fs) readMetaDataForIDPath(ctx context.Context, id, path string, directo } return nil, fs.ErrorDirNotFound } - return nil, errors.Wrap(err, "couldn't find item") + return nil, fmt.Errorf("couldn't find item: %w", err) } if directoriesOnly && item.Type != api.ItemTypeFolder { return nil, fs.ErrorIsFile @@ -386,10 +386,10 @@ func errorHandler(resp *http.Response) error { func checkUploadChunkSize(cs fs.SizeSuffix) error { if cs < minChunkSize { - return errors.Errorf("ChunkSize: %s is less than %s", cs, minChunkSize) + return fmt.Errorf("ChunkSize: %s is less than %s", cs, minChunkSize) } if cs > maxChunkSize { - return errors.Errorf("ChunkSize: %s is greater than %s", cs, maxChunkSize) + return fmt.Errorf("ChunkSize: %s is greater than %s", cs, maxChunkSize) } return nil } @@ -444,7 +444,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e var ts *oauthutil.TokenSource client, ts, err = oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure sharefile") + return nil, fmt.Errorf("failed to configure sharefile: %w", err) } ci := fs.GetConfig(ctx) @@ -477,23 +477,23 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e const serverTimezone = "America/New_York" timezone, err := tzdata.Open(serverTimezone) if err != nil { - return nil, errors.Wrap(err, "failed to open timezone db") + return nil, fmt.Errorf("failed to open timezone db: %w", err) } tzdata, err := ioutil.ReadAll(timezone) if err != nil { - return nil, errors.Wrap(err, "failed to read timezone") + return nil, fmt.Errorf("failed to read timezone: %w", err) } _ = timezone.Close() f.location, err = time.LoadLocationFromTZData(serverTimezone, tzdata) if err != nil { - return nil, errors.Wrap(err, "failed to load location from timezone") + return nil, fmt.Errorf("failed to load location from timezone: %w", err) } // Find ID of user's root folder if opt.RootFolderID == "" { item, err := f.readMetaDataForID(ctx, opt.RootFolderID, true, false) if err != nil { - return nil, errors.Wrap(err, "couldn't find root ID") + return nil, fmt.Errorf("couldn't find root ID: %w", err) } f.rootID = item.ID } else { @@ -639,7 +639,7 @@ func (f *Fs) CreateDir(ctx context.Context, pathID, leaf string) (newID string, return shouldRetry(ctx, resp, err) }) if err != nil { - return "", errors.Wrap(err, "CreateDir") + return "", fmt.Errorf("CreateDir: %w", err) } return info.ID, nil } @@ -671,7 +671,7 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } for i := range result.Value { item := &result.Value[i] @@ -825,7 +825,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return true }) if err != nil { - return errors.Wrap(err, "purgeCheck") + return fmt.Errorf("purgeCheck: %w", err) } if found { return fs.ErrorDirectoryNotEmpty @@ -900,7 +900,7 @@ func (f *Fs) updateItem(ctx context.Context, id, leaf, directoryID string, modTi // Parse it back into a time newModTime, err := time.Parse(time.RFC3339Nano, isoTime) if err != nil { - return nil, errors.Wrap(err, "updateItem: time parse") + return nil, fmt.Errorf("updateItem: time parse: %w", err) } modTime = &newModTime } @@ -934,7 +934,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir // To demonstrate bug // item, err = f.updateItem(ctx, id, newLeaf, newDirectoryID, nil) // if err != nil { - // return nil, errors.Wrap(err, "Move rename leaf") + // return nil, fmt.Errorf("Move rename leaf: %w", err) // } // return item, nil doRenameLeaf := oldLeaf != newLeaf @@ -947,7 +947,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir tmpLeaf := newLeaf + "." + random.String(8) item, err = f.updateItem(ctx, id, tmpLeaf, "", nil) if err != nil { - return nil, errors.Wrap(err, "Move rename leaf") + return nil, fmt.Errorf("Move rename leaf: %w", err) } } @@ -956,7 +956,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir if doMove { item, err = f.updateItem(ctx, id, "", newDirectoryID, nil) if err != nil { - return nil, errors.Wrap(err, "Move directory") + return nil, fmt.Errorf("Move directory: %w", err) } } @@ -964,7 +964,7 @@ func (f *Fs) move(ctx context.Context, isFile bool, id, oldLeaf, newLeaf, oldDir if doRenameLeaf { item, err = f.updateItem(ctx, id, newLeaf, "", nil) if err != nil { - return nil, errors.Wrap(err, "Move rename leaf") + return nil, fmt.Errorf("Move rename leaf: %w", err) } } @@ -1079,7 +1079,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (dst fs.Obj sameName := strings.ToLower(srcLeaf) == strings.ToLower(dstLeaf) if sameName && srcParentID == dstParentID { - return nil, errors.Errorf("copy: can't copy to a file in the same directory whose name only differs in case: %q vs %q", srcLeaf, dstLeaf) + return nil, fmt.Errorf("copy: can't copy to a file in the same directory whose name only differs in case: %q vs %q", srcLeaf, dstLeaf) } // Discover whether we can just copy directly or not @@ -1095,7 +1095,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (dst fs.Obj if err == fs.ErrorObjectNotFound || err == fs.ErrorDirNotFound { directCopy = true } else if err != nil { - return nil, errors.Wrap(err, "copy: failed to examine destination dir") + return nil, fmt.Errorf("copy: failed to examine destination dir: %w", err) } else { // otherwise need to copy via a temporary directory } @@ -1109,17 +1109,17 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (dst fs.Obj tmpDir := "rclone-temp-dir-" + random.String(16) err = f.Mkdir(ctx, tmpDir) if err != nil { - return nil, errors.Wrap(err, "copy: failed to make temp dir") + return nil, fmt.Errorf("copy: failed to make temp dir: %w", err) } defer func() { rmdirErr := f.Rmdir(ctx, tmpDir) if rmdirErr != nil && err == nil { - err = errors.Wrap(rmdirErr, "copy: failed to remove temp dir") + err = fmt.Errorf("copy: failed to remove temp dir: %w", rmdirErr) } }() tmpDirID, err := f.dirCache.FindDir(ctx, tmpDir, false) if err != nil { - return nil, errors.Wrap(err, "copy: failed to find temp dir") + return nil, fmt.Errorf("copy: failed to find temp dir: %w", err) } copyTargetDirID = tmpDirID } @@ -1221,7 +1221,7 @@ func (o *Object) Size() int64 { // setMetaData sets the metadata from info func (o *Object) setMetaData(info *api.Item) (err error) { if info.Type != api.ItemTypeFile { - return errors.Wrapf(fs.ErrorNotAFile, "%q is %q", o.remote, info.Type) + return fmt.Errorf("%q is %q: %w", o.remote, info.Type, fs.ErrorNotAFile) } o.hasMetaData = true o.size = info.Size @@ -1302,7 +1302,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "open: fetch download specification") + return nil, fmt.Errorf("open: fetch download specification: %w", err) } fs.FixRangeOption(options, o.size) @@ -1317,7 +1317,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "open") + return nil, fmt.Errorf("open: %w", err) } return resp.Body, err } @@ -1373,7 +1373,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "upload get specification") + return fmt.Errorf("upload get specification: %w", err) } // If file is large then upload in parts @@ -1398,7 +1398,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "upload file") + return fmt.Errorf("upload file: %w", err) } return o.checkUploadResponse(ctx, &finish) } @@ -1434,7 +1434,7 @@ func (f *Fs) remove(ctx context.Context, id string) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "remove") + return fmt.Errorf("remove: %w", err) } return nil } @@ -1443,7 +1443,7 @@ func (f *Fs) remove(ctx context.Context, id string) (err error) { func (o *Object) Remove(ctx context.Context) error { err := o.readMetaData(ctx) if err != nil { - return errors.Wrap(err, "Remove: Failed to read metadata") + return fmt.Errorf("Remove: Failed to read metadata: %w", err) } return o.fs.remove(ctx, o.id) } diff --git a/backend/sharefile/upload.go b/backend/sharefile/upload.go index f6ee40c86..eb8358b65 100644 --- a/backend/sharefile/upload.go +++ b/backend/sharefile/upload.go @@ -15,7 +15,6 @@ import ( "strings" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/sharefile/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -55,7 +54,7 @@ func (f *Fs) newLargeUpload(ctx context.Context, o *Object, in io.Reader, src fs case "threaded": streamed = false default: - return nil, errors.Errorf("can't use method %q with newLargeUpload", info.Method) + return nil, fmt.Errorf("can't use method %q with newLargeUpload", info.Method) } threads := f.ci.Transfers @@ -87,7 +86,7 @@ func (up *largeUpload) parseUploadFinishResponse(respBody []byte) (err error) { err = json.Unmarshal(respBody, &finish) if err != nil { // Sometimes the unmarshal fails in which case return the body - return errors.Errorf("upload: bad response: %q", bytes.TrimSpace(respBody)) + return fmt.Errorf("upload: bad response: %q", bytes.TrimSpace(respBody)) } return up.o.checkUploadResponse(up.ctx, &finish) } @@ -240,7 +239,7 @@ outer: // check size read is correct if eof && err == nil && up.size >= 0 && up.size != offset { - err = errors.Errorf("upload: short read: read %d bytes expected %d", up.size, offset) + err = fmt.Errorf("upload: short read: read %d bytes expected %d", up.size, offset) } // read any errors diff --git a/backend/sia/sia.go b/backend/sia/sia.go index 749445ebf..2017332ce 100644 --- a/backend/sia/sia.go +++ b/backend/sia/sia.go @@ -3,6 +3,7 @@ package sia import ( "context" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -11,18 +12,16 @@ import ( "strings" "time" - "github.com/rclone/rclone/fs/config" - "github.com/rclone/rclone/lib/encoder" - - "github.com/pkg/errors" "github.com/rclone/rclone/backend/sia/api" "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" "github.com/rclone/rclone/fs/config/obscure" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fshttp" "github.com/rclone/rclone/fs/hash" + "github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/rest" ) @@ -460,7 +459,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if opt.APIPassword != "" { opt.APIPassword, err = obscure.Reveal(opt.APIPassword) if err != nil { - return nil, errors.Wrap(err, "couldn't decrypt API password") + return nil, fmt.Errorf("couldn't decrypt API password: %w", err) } f.srv.SetUserPass("", opt.APIPassword) } @@ -474,7 +473,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } _, err := f.NewObject(ctx, remote) if err != nil { - if errors.Cause(err) == fs.ErrorObjectNotFound || errors.Cause(err) == fs.ErrorNotAFile { + if errors.Is(err, fs.ErrorObjectNotFound) || errors.Is(err, fs.ErrorNotAFile) { // File doesn't exist so return old f f.root = root return f, nil @@ -493,7 +492,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e func errorHandler(resp *http.Response) error { body, err := rest.ReadBody(resp) if err != nil { - return errors.Wrap(err, "error when trying to read error body") + return fmt.Errorf("error when trying to read error body: %w", err) } // Decode error response errResponse := new(api.Error) diff --git a/backend/sugarsync/sugarsync.go b/backend/sugarsync/sugarsync.go index 35801090b..4b57f4184 100644 --- a/backend/sugarsync/sugarsync.go +++ b/backend/sugarsync/sugarsync.go @@ -14,6 +14,7 @@ To work around this we use the remote "TestSugarSync:Test" to test with. import ( "context" + "errors" "fmt" "io" "net/http" @@ -25,7 +26,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/sugarsync/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -79,7 +79,7 @@ func init() { opt := new(Options) err := configstruct.Set(m, opt) if err != nil { - return nil, errors.Wrap(err, "failed to read options") + return nil, fmt.Errorf("failed to read options: %w", err) } switch config.State { @@ -124,7 +124,7 @@ func init() { // return shouldRetry(ctx, resp, err) //}) if err != nil { - return nil, errors.Wrap(err, "failed to get token") + return nil, fmt.Errorf("failed to get token: %w", err) } opt.RefreshToken = resp.Header.Get("Location") m.Set("refresh_token", opt.RefreshToken) @@ -309,7 +309,7 @@ func (f *Fs) readMetaDataForID(ctx context.Context, ID string) (info *api.File, if resp != nil && resp.StatusCode == http.StatusNotFound { return nil, fs.ErrorObjectNotFound } - return nil, errors.Wrap(err, "failed to get authorization") + return nil, fmt.Errorf("failed to get authorization: %w", err) } return info, nil } @@ -343,7 +343,7 @@ func (f *Fs) getAuthToken(ctx context.Context) error { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to get authorization") + return fmt.Errorf("failed to get authorization: %w", err) } f.opt.Authorization = resp.Header.Get("Location") f.authExpiry = authResponse.Expiration @@ -391,7 +391,7 @@ func (f *Fs) getUser(ctx context.Context) (user *api.User, err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "failed to get user") + return nil, fmt.Errorf("failed to get user: %w", err) } return user, nil } @@ -445,7 +445,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e if strings.HasSuffix(f.opt.RootID, "/contents") { f.opt.RootID = f.opt.RootID[:len(f.opt.RootID)-9] } else { - return nil, errors.Errorf("unexpected rootID %q", f.opt.RootID) + return nil, fmt.Errorf("unexpected rootID %q", f.opt.RootID) } // Cache the results f.m.Set("root_id", f.opt.RootID) @@ -497,13 +497,13 @@ var findError = regexp.MustCompile(`

(.*?)

`) func errorHandler(resp *http.Response) (err error) { body, err := rest.ReadBody(resp) if err != nil { - return errors.Wrap(err, "error reading error out of body") + return fmt.Errorf("error reading error out of body: %w", err) } match := findError.FindSubmatch(body) if match == nil || len(match) < 2 || len(match[1]) == 0 { - return errors.Errorf("HTTP error %v (%v) returned body: %q", resp.StatusCode, resp.Status, body) + return fmt.Errorf("HTTP error %v (%v) returned body: %q", resp.StatusCode, resp.Status, body) } - return errors.Errorf("HTTP error %v (%v): %s", resp.StatusCode, resp.Status, match[1]) + return fmt.Errorf("HTTP error %v (%v): %s", resp.StatusCode, resp.Status, match[1]) } // rootSlash returns root with a slash on if it is empty, otherwise empty string @@ -596,7 +596,7 @@ func (f *Fs) CreateDir(ctx context.Context, pathID, leaf string) (newID string, return "", err } if !found { - return "", errors.Errorf("couldn't find ID for newly created directory %q", leaf) + return "", fmt.Errorf("couldn't find ID for newly created directory %q", leaf) } } @@ -636,7 +636,7 @@ OUTER: return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } if fileFn != nil { for i := range result.Files { @@ -873,7 +873,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, srcPath := srcObj.fs.rootSlash() + srcObj.remote dstPath := f.rootSlash() + remote if strings.ToLower(srcPath) == strings.ToLower(dstPath) { - return nil, errors.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) + return nil, fmt.Errorf("can't copy %q -> %q as are same name when lowercase", srcPath, dstPath) } // Create temporary object @@ -1247,7 +1247,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op if o.id == "" { o.id, err = o.fs.createFile(ctx, directoryID, leaf, fs.MimeType(ctx, src)) if err != nil { - return errors.Wrap(err, "failed to create file") + return fmt.Errorf("failed to create file: %w", err) } if o.id == "" { return errors.New("failed to create file: no ID") @@ -1280,7 +1280,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "failed to upload file") + return fmt.Errorf("failed to upload file: %w", err) } o.hasMetaData = false diff --git a/backend/swift/swift.go b/backend/swift/swift.go index 0dcead728..03b496301 100644 --- a/backend/swift/swift.go +++ b/backend/swift/swift.go @@ -5,6 +5,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "io" "net/url" @@ -15,7 +16,6 @@ import ( "github.com/google/uuid" "github.com/ncw/swift/v2" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -381,7 +381,7 @@ func swiftConnection(ctx context.Context, opt *Options, name string) (*swift.Con if opt.EnvAuth { err := c.ApplyEnvironment() if err != nil { - return nil, errors.Wrap(err, "failed to read environment variables") + return nil, fmt.Errorf("failed to read environment variables: %w", err) } } StorageUrl, AuthToken := c.StorageUrl, c.AuthToken // nolint @@ -423,7 +423,7 @@ func swiftConnection(ctx context.Context, opt *Options, name string) (*swift.Con func checkUploadChunkSize(cs fs.SizeSuffix) error { const minChunkSize = fs.SizeSuffixBase if cs < minChunkSize { - return errors.Errorf("%s is less than %s", cs, minChunkSize) + return fmt.Errorf("%s is less than %s", cs, minChunkSize) } return nil } @@ -499,7 +499,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } err = checkUploadChunkSize(opt.ChunkSize) if err != nil { - return nil, errors.Wrap(err, "swift: chunk size") + return nil, fmt.Errorf("swift: chunk size: %w", err) } c, err := swiftConnection(ctx, opt, name) @@ -670,7 +670,7 @@ func (f *Fs) listContainers(ctx context.Context) (entries fs.DirEntries, err err return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "container listing failed") + return nil, fmt.Errorf("container listing failed: %w", err) } for _, container := range containers { f.cache.MarkOK(container.Name) @@ -762,7 +762,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { return shouldRetry(ctx, err) }) if err != nil { - return nil, errors.Wrap(err, "container listing failed") + return nil, fmt.Errorf("container listing failed: %w", err) } var total, objects int64 for _, c := range containers { diff --git a/backend/tardigrade/fs.go b/backend/tardigrade/fs.go index 0613ca2d6..afe9f55e5 100644 --- a/backend/tardigrade/fs.go +++ b/backend/tardigrade/fs.go @@ -6,13 +6,13 @@ package tardigrade import ( "context" + "errors" "fmt" "io" "path" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -64,12 +64,12 @@ func init() { access, err := uplink.RequestAccessWithPassphrase(context.TODO(), satellite, apiKey, passphrase) if err != nil { - return nil, errors.Wrap(err, "couldn't create access grant") + return nil, fmt.Errorf("couldn't create access grant: %w", err) } serializedAccess, err := access.Serialize() if err != nil { - return nil, errors.Wrap(err, "couldn't serialize access grant") + return nil, fmt.Errorf("couldn't serialize access grant: %w", err) } m.Set("satellite_address", satellite) m.Set("access_grant", serializedAccess) @@ -78,7 +78,7 @@ func init() { config.FileDeleteKey(name, "api_key") config.FileDeleteKey(name, "passphrase") } else { - return nil, errors.Errorf("invalid provider type: %s", provider) + return nil, fmt.Errorf("invalid provider type: %s", provider) } return nil, nil }, @@ -188,24 +188,24 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (_ fs.Fs, if f.opts.Access != "" { access, err = uplink.ParseAccess(f.opts.Access) if err != nil { - return nil, errors.Wrap(err, "tardigrade: access") + return nil, fmt.Errorf("tardigrade: access: %w", err) } } if access == nil && f.opts.SatelliteAddress != "" && f.opts.APIKey != "" && f.opts.Passphrase != "" { access, err = uplink.RequestAccessWithPassphrase(ctx, f.opts.SatelliteAddress, f.opts.APIKey, f.opts.Passphrase) if err != nil { - return nil, errors.Wrap(err, "tardigrade: access") + return nil, fmt.Errorf("tardigrade: access: %w", err) } serializedAccess, err := access.Serialize() if err != nil { - return nil, errors.Wrap(err, "tardigrade: access") + return nil, fmt.Errorf("tardigrade: access: %w", err) } err = config.SetValueAndSave(f.name, "access_grant", serializedAccess) if err != nil { - return nil, errors.Wrap(err, "tardigrade: access") + return nil, fmt.Errorf("tardigrade: access: %w", err) } } @@ -237,7 +237,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (_ fs.Fs, if bucketName != "" && bucketPath != "" { _, err = project.StatBucket(ctx, bucketName) if err != nil { - return f, errors.Wrap(err, "tardigrade: bucket") + return f, fmt.Errorf("tardigrade: bucket: %w", err) } object, err := project.StatObject(ctx, bucketName, bucketPath) @@ -274,7 +274,7 @@ func (f *Fs) connect(ctx context.Context) (project *uplink.Project, err error) { project, err = cfg.OpenProject(ctx, f.access) if err != nil { - return nil, errors.Wrap(err, "tardigrade: project") + return nil, fmt.Errorf("tardigrade: project: %w", err) } return diff --git a/backend/tardigrade/object.go b/backend/tardigrade/object.go index 581070d69..2d8372a7d 100644 --- a/backend/tardigrade/object.go +++ b/backend/tardigrade/object.go @@ -5,11 +5,11 @@ package tardigrade import ( "context" + "errors" "io" "path" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/lib/bucket" diff --git a/backend/union/entry.go b/backend/union/entry.go index 31378e710..9142a61a0 100644 --- a/backend/union/entry.go +++ b/backend/union/entry.go @@ -2,11 +2,11 @@ package union import ( "context" + "fmt" "io" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/union/upstream" "github.com/rclone/rclone/fs" ) @@ -82,7 +82,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op multithread(len(entries), func(i int) { if o, ok := entries[i].(*upstream.Object); ok { err := o.Update(ctx, readers[i], src, options...) - errs[i] = errors.Wrap(err, o.UpstreamFs().Name()) + errs[i] = fmt.Errorf("%s: %w", o.UpstreamFs().Name(), err) } else { errs[i] = fs.ErrorNotAFile } @@ -101,7 +101,7 @@ func (o *Object) Remove(ctx context.Context) error { multithread(len(entries), func(i int) { if o, ok := entries[i].(*upstream.Object); ok { err := o.Remove(ctx) - errs[i] = errors.Wrap(err, o.UpstreamFs().Name()) + errs[i] = fmt.Errorf("%s: %w", o.UpstreamFs().Name(), err) } else { errs[i] = fs.ErrorNotAFile } @@ -120,7 +120,7 @@ func (o *Object) SetModTime(ctx context.Context, t time.Time) error { multithread(len(entries), func(i int) { if o, ok := entries[i].(*upstream.Object); ok { err := o.SetModTime(ctx, t) - errs[i] = errors.Wrap(err, o.UpstreamFs().Name()) + errs[i] = fmt.Errorf("%s: %w", o.UpstreamFs().Name(), err) } else { errs[i] = fs.ErrorNotAFile } diff --git a/backend/union/policy/policy.go b/backend/union/policy/policy.go index 19cee2e01..d784c8e29 100644 --- a/backend/union/policy/policy.go +++ b/backend/union/policy/policy.go @@ -2,12 +2,12 @@ package policy import ( "context" + "fmt" "math/rand" "path" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/union/upstream" "github.com/rclone/rclone/fs" ) @@ -44,7 +44,7 @@ func registerPolicy(name string, p Policy) { func Get(name string) (Policy, error) { p, ok := policies[strings.ToLower(name)] if !ok { - return nil, errors.Errorf("didn't find policy called %q", name) + return nil, fmt.Errorf("didn't find policy called %q", name) } return p, nil } diff --git a/backend/union/union.go b/backend/union/union.go index 7c3951771..c3fb2e26b 100644 --- a/backend/union/union.go +++ b/backend/union/union.go @@ -3,6 +3,7 @@ package union import ( "bufio" "context" + "errors" "fmt" "io" "path" @@ -11,7 +12,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/union/policy" "github.com/rclone/rclone/backend/union/upstream" "github.com/rclone/rclone/fs" @@ -99,7 +99,7 @@ func (f *Fs) wrapEntries(entries ...upstream.Entry) (entry, error) { cd: entries, }, nil default: - return nil, errors.Errorf("unknown object type %T", e) + return nil, fmt.Errorf("unknown object type %T", e) } } @@ -132,7 +132,7 @@ func (f *Fs) Rmdir(ctx context.Context, dir string) error { errs := Errors(make([]error, len(upstreams))) multithread(len(upstreams), func(i int) { err := upstreams[i].Rmdir(ctx, dir) - errs[i] = errors.Wrap(err, upstreams[i].Name()) + errs[i] = fmt.Errorf("%s: %w", upstreams[i].Name(), err) }) return errs.Err() } @@ -162,7 +162,7 @@ func (f *Fs) Mkdir(ctx context.Context, dir string) error { errs := Errors(make([]error, len(upstreams))) multithread(len(upstreams), func(i int) { err := upstreams[i].Mkdir(ctx, dir) - errs[i] = errors.Wrap(err, upstreams[i].Name()) + errs[i] = fmt.Errorf("%s: %w", upstreams[i].Name(), err) }) return errs.Err() } @@ -186,10 +186,10 @@ func (f *Fs) Purge(ctx context.Context, dir string) error { errs := Errors(make([]error, len(upstreams))) multithread(len(upstreams), func(i int) { err := upstreams[i].Features().Purge(ctx, dir) - if errors.Cause(err) == fs.ErrorDirNotFound { + if errors.Is(err, fs.ErrorDirNotFound) { err = nil } - errs[i] = errors.Wrap(err, upstreams[i].Name()) + errs[i] = fmt.Errorf("%s: %w", upstreams[i].Name(), err) }) return errs.Err() } @@ -264,7 +264,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, su := entries[i].UpstreamFs() o, ok := entries[i].(*upstream.Object) if !ok { - errs[i] = errors.Wrap(fs.ErrorNotAFile, su.Name()) + errs[i] = fmt.Errorf("%s: %w", su.Name(), fs.ErrorNotAFile) return } var du *upstream.Fs @@ -274,7 +274,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } } if du == nil { - errs[i] = errors.Wrap(fs.ErrorCantMove, su.Name()+":"+remote) + errs[i] = fmt.Errorf("%s: %s: %w", su.Name(), remote, fs.ErrorCantMove) return } srcObj := o.UnWrap() @@ -286,7 +286,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, // Do the Move or Copy dstObj, err := do(ctx, srcObj, remote) if err != nil || dstObj == nil { - errs[i] = errors.Wrap(err, su.Name()) + errs[i] = fmt.Errorf("%s: %w", su.Name(), err) return } objs[i] = du.WrapObject(dstObj) @@ -294,7 +294,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, if duFeatures.Move == nil { err = srcObj.Remove(ctx) if err != nil { - errs[i] = errors.Wrap(err, su.Name()) + errs[i] = fmt.Errorf("%s: %w", su.Name(), err) return } } @@ -345,18 +345,18 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string } } if du == nil { - errs[i] = errors.Wrap(fs.ErrorCantDirMove, su.Name()+":"+su.Root()) + errs[i] = fmt.Errorf("%s: %s: %w", su.Name(), su.Root(), fs.ErrorCantDirMove) return } err := du.Features().DirMove(ctx, su.Fs, srcRemote, dstRemote) - errs[i] = errors.Wrap(err, du.Name()+":"+du.Root()) + errs[i] = fmt.Errorf("%s: %w", du.Name()+":"+du.Root(), err) }) errs = errs.FilterNil() if len(errs) == 0 { return nil } for _, e := range errs { - if errors.Cause(e) != fs.ErrorDirExists { + if !errors.Is(e, fs.ErrorDirExists) { return errs } } @@ -477,7 +477,7 @@ func (f *Fs) put(ctx context.Context, in io.Reader, src fs.ObjectInfo, stream bo o, err = u.Put(ctx, readers[i], src, options...) } if err != nil { - errs[i] = errors.Wrap(err, u.Name()) + errs[i] = fmt.Errorf("%s: %w", u.Name(), err) return } objs[i] = u.WrapObject(o) @@ -537,7 +537,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { } for _, u := range f.upstreams { usg, err := u.About(ctx) - if errors.Cause(err) == fs.ErrorDirNotFound { + if errors.Is(err, fs.ErrorDirNotFound) { continue } if err != nil { @@ -593,7 +593,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e u := f.upstreams[i] entries, err := u.List(ctx, dir) if err != nil { - errs[i] = errors.Wrap(err, u.Name()) + errs[i] = fmt.Errorf("%s: %w", u.Name(), err) return } uEntries := make([]upstream.Entry, len(entries)) @@ -604,7 +604,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e }) if len(errs) == len(errs.FilterNil()) { errs = errs.Map(func(e error) error { - if errors.Cause(e) == fs.ErrorDirNotFound { + if errors.Is(e, fs.ErrorDirNotFound) { return nil } return e @@ -657,13 +657,13 @@ func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) ( err = walk.ListR(ctx, u, dir, true, -1, walk.ListAll, callback) } if err != nil { - errs[i] = errors.Wrap(err, u.Name()) + errs[i] = fmt.Errorf("%s: %w", u.Name(), err) return } }) if len(errs) == len(errs.FilterNil()) { errs = errs.Map(func(e error) error { - if errors.Cause(e) == fs.ErrorDirNotFound { + if errors.Is(e, fs.ErrorDirNotFound) { return nil } return e @@ -688,7 +688,7 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { u := f.upstreams[i] o, err := u.NewObject(ctx, remote) if err != nil && err != fs.ErrorObjectNotFound { - errs[i] = errors.Wrap(err, u.Name()) + errs[i] = fmt.Errorf("%s: %w", u.Name(), err) return } objs[i] = u.WrapObject(o) @@ -777,7 +777,7 @@ func (f *Fs) Shutdown(ctx context.Context) error { u := f.upstreams[i] if do := u.Features().Shutdown; do != nil { err := do(ctx) - errs[i] = errors.Wrap(err, u.Name()) + errs[i] = fmt.Errorf("%s: %w", u.Name(), err) } }) return errs.Err() diff --git a/backend/union/upstream/upstream.go b/backend/union/upstream/upstream.go index 93bce52e9..93b8ae521 100644 --- a/backend/union/upstream/upstream.go +++ b/backend/union/upstream/upstream.go @@ -2,6 +2,8 @@ package upstream import ( "context" + "errors" + "fmt" "io" "math" "path" @@ -11,7 +13,6 @@ import ( "sync/atomic" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/fspath" @@ -133,7 +134,7 @@ func (f *Fs) WrapEntry(e fs.DirEntry) (Entry, error) { case fs.Directory: return f.WrapDirectory(e.(fs.Directory)), nil default: - return nil, errors.Errorf("unknown object type %T", e) + return nil, fmt.Errorf("unknown object type %T", e) } } @@ -335,7 +336,7 @@ func (f *Fs) updateUsageCore(lock bool) error { usage, err := f.RootFs.Features().About(ctx) if err != nil { f.cacheUpdate = false - if errors.Cause(err) == fs.ErrorDirNotFound { + if errors.Is(err, fs.ErrorDirNotFound) { err = nil } return err diff --git a/backend/uptobox/uptobox.go b/backend/uptobox/uptobox.go index 3f1448a30..94ef96fd9 100644 --- a/backend/uptobox/uptobox.go +++ b/backend/uptobox/uptobox.go @@ -3,6 +3,7 @@ package uptobox import ( "context" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -14,7 +15,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/uptobox/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -408,7 +408,7 @@ func (f *Fs) uploadFile(ctx context.Context, in io.Reader, size int64, filename return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't upload file") + return nil, fmt.Errorf("couldn't upload file: %w", err) } return &ul, nil } @@ -438,10 +438,10 @@ func (f *Fs) move(ctx context.Context, dstPath string, fileID string) (err error return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't move file") + return fmt.Errorf("couldn't move file: %w", err) } if info.StatusCode != 0 { - return errors.Errorf("move: api error: %d - %s", info.StatusCode, info.Message) + return fmt.Errorf("move: api error: %d - %s", info.StatusCode, info.Message) } return err } @@ -460,10 +460,10 @@ func (f *Fs) updateFileInformation(ctx context.Context, update *api.UpdateFileIn return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't update file info") + return fmt.Errorf("couldn't update file info: %w", err) } if info.StatusCode != 0 { - return errors.Errorf("updateFileInfo: api error: %d - %s", info.StatusCode, info.Message) + return fmt.Errorf("updateFileInfo: api error: %d - %s", info.StatusCode, info.Message) } return err } @@ -493,7 +493,7 @@ func (f *Fs) putUnchecked(ctx context.Context, in io.Reader, remote string, size return nil, err } if info.StatusCode != 0 { - return nil, errors.Errorf("putUnchecked: api error: %d - %s", info.StatusCode, info.Message) + return nil, fmt.Errorf("putUnchecked: api error: %d - %s", info.StatusCode, info.Message) } // we need to have a safe name for the upload to work tmpName := "rcloneTemp" + random.String(8) @@ -681,7 +681,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, if needMove { err := f.mkDirs(ctx, strings.Trim(dstBase, "/")) if err != nil { - return nil, errors.Wrap(err, "move: failed to make destination dirs") + return nil, fmt.Errorf("move: failed to make destination dirs: %w", err) } err = f.move(ctx, dstBase, srcObj.code) @@ -694,7 +694,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, if needRename { err := f.updateFileInformation(ctx, &api.UpdateFileInformation{Token: f.opt.AccessToken, FileCode: srcObj.code, NewName: f.opt.Enc.FromStandardName(dstLeaf)}) if err != nil { - return nil, errors.Wrap(err, "move: failed final rename") + return nil, fmt.Errorf("move: failed final rename: %w", err) } } @@ -751,7 +751,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string srcPath := srcFs.dirPath(srcRemote) srcInfo, err := f.readMetaDataForPath(ctx, srcPath, &api.MetadataRequestOptions{Limit: 1}) if err != nil { - return errors.Wrap(err, "dirmove: source not found") + return fmt.Errorf("dirmove: source not found: %w", err) } // check if the destination allready exists dstPath := f.dirPath(dstRemote) @@ -764,13 +764,13 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string dstBase, dstName := f.splitPathFull(dstRemote) err = f.mkDirs(ctx, strings.Trim(dstBase, "/")) if err != nil { - return errors.Wrap(err, "dirmove: failed to create dirs") + return fmt.Errorf("dirmove: failed to create dirs: %w", err) } // find the destination parent dir dstInfo, err = f.readMetaDataForPath(ctx, dstBase, &api.MetadataRequestOptions{Limit: 1}) if err != nil { - return errors.Wrap(err, "dirmove: failed to read destination") + return fmt.Errorf("dirmove: failed to read destination: %w", err) } srcBase, srcName := srcFs.splitPathFull(srcRemote) @@ -784,7 +784,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string tmpName := "rcloneTemp" + random.String(8) err = f.renameDir(ctx, srcInfo.Data.CurrentFolder.FolderID, tmpName) if err != nil { - return errors.Wrap(err, "dirmove: failed initial rename") + return fmt.Errorf("dirmove: failed initial rename: %w", err) } } @@ -807,7 +807,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "dirmove: failed to move") + return fmt.Errorf("dirmove: failed to move: %w", err) } if apiErr.StatusCode != 0 { return apiErr @@ -818,7 +818,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string if needRename { err = f.renameDir(ctx, srcInfo.Data.CurrentFolder.FolderID, dstName) if err != nil { - return errors.Wrap(err, "dirmove: failed final rename") + return fmt.Errorf("dirmove: failed final rename: %w", err) } } return nil @@ -848,10 +848,10 @@ func (f *Fs) copy(ctx context.Context, dstPath string, fileID string) (err error return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "couldn't copy file") + return fmt.Errorf("couldn't copy file: %w", err) } if info.StatusCode != 0 { - return errors.Errorf("copy: api error: %d - %s", info.StatusCode, info.Message) + return fmt.Errorf("copy: api error: %d - %s", info.StatusCode, info.Message) } return err } @@ -871,7 +871,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, err := f.mkDirs(ctx, path.Join(f.root, dstBase)) if err != nil { - return nil, errors.Wrap(err, "copy: failed to make destination dirs") + return nil, fmt.Errorf("copy: failed to make destination dirs: %w", err) } err = f.copy(ctx, f.dirPath(dstBase), srcObj.code) @@ -881,13 +881,13 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, newObj, err := f.NewObject(ctx, path.Join(dstBase, srcLeaf)) if err != nil { - return nil, errors.Wrap(err, "copy: couldn't find copied object") + return nil, fmt.Errorf("copy: couldn't find copied object: %w", err) } if needRename { err := f.updateFileInformation(ctx, &api.UpdateFileInformation{Token: f.opt.AccessToken, FileCode: newObj.(*Object).code, NewName: f.opt.Enc.FromStandardName(dstLeaf)}) if err != nil { - return nil, errors.Wrap(err, "copy: failed final rename") + return nil, fmt.Errorf("copy: failed final rename: %w", err) } newObj.(*Object).remote = remote } @@ -970,7 +970,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "open: failed to get download link") + return nil, fmt.Errorf("open: failed to get download link: %w", err) } fs.FixRangeOption(options, o.size) @@ -1010,7 +1010,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // delete duplicate object after successful upload err = o.Remove(ctx) if err != nil { - return errors.Wrap(err, "failed to remove old version") + return fmt.Errorf("failed to remove old version: %w", err) } // Replace guts of old object with new one @@ -1038,7 +1038,7 @@ func (o *Object) Remove(ctx context.Context) error { return err } if info.StatusCode != 0 { - return errors.Errorf("remove: api error: %d - %s", info.StatusCode, info.Message) + return fmt.Errorf("remove: api error: %d - %s", info.StatusCode, info.Message) } return nil } diff --git a/backend/webdav/odrvcookie/fetch.go b/backend/webdav/odrvcookie/fetch.go index 5e7f84bf9..f6b25d29e 100644 --- a/backend/webdav/odrvcookie/fetch.go +++ b/backend/webdav/odrvcookie/fetch.go @@ -13,7 +13,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fshttp" "golang.org/x/net/publicsuffix" @@ -122,12 +121,12 @@ func (ca *CookieAuth) Cookies(ctx context.Context) (*CookieResponse, error) { func (ca *CookieAuth) getSPCookie(conf *SharepointSuccessResponse) (*CookieResponse, error) { spRoot, err := url.Parse(ca.endpoint) if err != nil { - return nil, errors.Wrap(err, "Error while constructing endpoint URL") + return nil, fmt.Errorf("error while constructing endpoint URL: %w", err) } u, err := url.Parse(spRoot.Scheme + "://" + spRoot.Host + "/_forms/default.aspx?wa=wsignin1.0") if err != nil { - return nil, errors.Wrap(err, "Error while constructing login URL") + return nil, fmt.Errorf("error while constructing login URL: %w", err) } // To authenticate with davfs or anything else we need two cookies (rtFa and FedAuth) @@ -143,7 +142,7 @@ func (ca *CookieAuth) getSPCookie(conf *SharepointSuccessResponse) (*CookieRespo // Send the previously acquired Token as a Post parameter if _, err = client.Post(u.String(), "text/xml", strings.NewReader(conf.Body.Token)); err != nil { - return nil, errors.Wrap(err, "Error while grabbing cookies from endpoint: %v") + return nil, fmt.Errorf("error while grabbing cookies from endpoint: %w", err) } cookieResponse := CookieResponse{} @@ -171,7 +170,7 @@ func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SharepointSuccessRe buf := &bytes.Buffer{} if err := t.Execute(buf, reqData); err != nil { - return nil, errors.Wrap(err, "Error while filling auth token template") + return nil, fmt.Errorf("error while filling auth token template: %w", err) } // Create and execute the first request which returns an auth token for the sharepoint service @@ -184,7 +183,7 @@ func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SharepointSuccessRe client := fshttp.NewClient(ctx) resp, err := client.Do(req) if err != nil { - return nil, errors.Wrap(err, "Error while logging in to endpoint") + return nil, fmt.Errorf("error while logging in to endpoint: %w", err) } defer fs.CheckClose(resp.Body, &err) @@ -209,7 +208,7 @@ func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SharepointSuccessRe } if err != nil { - return nil, errors.Wrap(err, "Error while reading endpoint response") + return nil, fmt.Errorf("error while reading endpoint response: %w", err) } return } diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go index 12f312530..9564ae601 100644 --- a/backend/webdav/webdav.go +++ b/backend/webdav/webdav.go @@ -12,6 +12,7 @@ import ( "context" "crypto/tls" "encoding/xml" + "errors" "fmt" "io" "net/http" @@ -23,7 +24,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/webdav/api" "github.com/rclone/rclone/backend/webdav/odrvcookie" "github.com/rclone/rclone/fs" @@ -303,7 +303,7 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, path string, depth string) } } if err != nil { - return nil, errors.Wrap(err, "read metadata failed") + return nil, fmt.Errorf("read metadata failed: %w", err) } if len(result.Responses) < 1 { return nil, fs.ErrorObjectNotFound @@ -322,7 +322,7 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, path string, depth string) func errorHandler(resp *http.Response) error { body, err := rest.ReadBody(resp) if err != nil { - return errors.Wrap(err, "error when trying to read error from body") + return fmt.Errorf("error when trying to read error from body: %w", err) } // Decode error response errResponse := new(api.Error) @@ -387,7 +387,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e var err error opt.Pass, err = obscure.Reveal(opt.Pass) if err != nil { - return nil, errors.Wrap(err, "couldn't decrypt password") + return nil, fmt.Errorf("couldn't decrypt password: %w", err) } } if opt.Vendor == "" { @@ -465,7 +465,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e } _, err := f.NewObject(ctx, remote) if err != nil { - if errors.Cause(err) == fs.ErrorObjectNotFound || errors.Cause(err) == fs.ErrorIsDir { + if errors.Is(err, fs.ErrorObjectNotFound) || errors.Is(err, fs.ErrorIsDir) { // File doesn't exist so return old f f.root = root return f, nil @@ -503,7 +503,7 @@ func (f *Fs) fetchBearerToken(cmd string) (string, error) { if stderrString == "" { stderrString = stdoutString } - return "", errors.Wrapf(err, "failed to get bearer token using %q: %s", f.opt.BearerTokenCommand, stderrString) + return "", fmt.Errorf("failed to get bearer token using %q: %s: %w", f.opt.BearerTokenCommand, stderrString, err) } return stdoutString, nil } @@ -673,12 +673,12 @@ func (f *Fs) listAll(ctx context.Context, dir string, directoriesOnly bool, file return found, fs.ErrorDirNotFound } } - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } //fmt.Printf("result = %#v", &result) baseURL, err := rest.URLJoin(f.endpoint, opts.Path) if err != nil { - return false, errors.Wrap(err, "couldn't join URL") + return false, fmt.Errorf("couldn't join URL: %w", err) } for i := range result.Responses { item := &result.Responses[i] @@ -947,7 +947,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return f.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } // FIXME parse Multistatus response return nil @@ -986,11 +986,11 @@ func (f *Fs) copyOrMove(ctx context.Context, src fs.Object, remote string, metho dstPath := f.filePath(remote) err := f.mkParentDir(ctx, dstPath) if err != nil { - return nil, errors.Wrap(err, "Copy mkParentDir failed") + return nil, fmt.Errorf("Copy mkParentDir failed: %w", err) } destinationURL, err := rest.URLJoin(f.endpoint, dstPath) if err != nil { - return nil, errors.Wrap(err, "copyOrMove couldn't join URL") + return nil, fmt.Errorf("copyOrMove couldn't join URL: %w", err) } var resp *http.Response opts := rest.Opts{ @@ -1010,11 +1010,11 @@ func (f *Fs) copyOrMove(ctx context.Context, src fs.Object, remote string, metho return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "Copy call failed") + return nil, fmt.Errorf("Copy call failed: %w", err) } dstObj, err := f.NewObject(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "Copy NewObject failed") + return nil, fmt.Errorf("Copy NewObject failed: %w", err) } return dstObj, nil } @@ -1077,18 +1077,18 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return fs.ErrorDirExists } if err != fs.ErrorDirNotFound { - return errors.Wrap(err, "DirMove dirExists dst failed") + return fmt.Errorf("DirMove dirExists dst failed: %w", err) } // Make sure the parent directory exists err = f.mkParentDir(ctx, dstPath) if err != nil { - return errors.Wrap(err, "DirMove mkParentDir dst failed") + return fmt.Errorf("DirMove mkParentDir dst failed: %w", err) } destinationURL, err := rest.URLJoin(f.endpoint, dstPath) if err != nil { - return errors.Wrap(err, "DirMove couldn't join URL") + return fmt.Errorf("DirMove couldn't join URL: %w", err) } var resp *http.Response @@ -1106,7 +1106,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return f.shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "DirMove MOVE call failed") + return fmt.Errorf("DirMove MOVE call failed: %w", err) } return nil } @@ -1148,7 +1148,7 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { return f.shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "about call failed") + return nil, fmt.Errorf("about call failed: %w", err) } usage := &fs.Usage{} if i, err := strconv.ParseInt(q.Used, 10, 64); err == nil && i >= 0 { @@ -1289,7 +1289,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) { err = o.fs.mkParentDir(ctx, o.filePath()) if err != nil { - return errors.Wrap(err, "Update mkParentDir failed") + return fmt.Errorf("Update mkParentDir failed: %w", err) } size := src.Size() diff --git a/backend/yandex/yandex.go b/backend/yandex/yandex.go index d1fa3321b..abcc24c27 100644 --- a/backend/yandex/yandex.go +++ b/backend/yandex/yandex.go @@ -3,6 +3,7 @@ package yandex import ( "context" "encoding/json" + "errors" "fmt" "io" "log" @@ -13,7 +14,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/yandex/api" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -249,7 +249,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e token, err := oauthutil.GetToken(name, m) if err != nil { - return nil, errors.Wrap(err, "couldn't read OAuth token") + return nil, fmt.Errorf("couldn't read OAuth token: %w", err) } if token.RefreshToken == "" { return nil, errors.New("unable to get RefreshToken. If you are upgrading from older versions of rclone, please run `rclone config` and re-configure this backend") @@ -258,13 +258,13 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e token.TokenType = "OAuth" err = oauthutil.PutToken(name, m, token, false) if err != nil { - return nil, errors.Wrap(err, "couldn't save OAuth token") + return nil, fmt.Errorf("couldn't save OAuth token: %w", err) } log.Printf("Automatically upgraded OAuth config.") } oAuthClient, _, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, errors.Wrap(err, "failed to configure Yandex") + return nil, fmt.Errorf("failed to configure Yandex: %w", err) } ci := fs.GetConfig(ctx) @@ -309,7 +309,7 @@ func (f *Fs) itemToDirEntry(ctx context.Context, remote string, object *api.Reso case "dir": t, err := time.Parse(time.RFC3339Nano, object.Modified) if err != nil { - return nil, errors.Wrap(err, "error parsing time in directory item") + return nil, fmt.Errorf("error parsing time in directory item: %w", err) } d := fs.NewDir(remote, t).SetSize(object.Size) return d, nil @@ -560,19 +560,19 @@ func (f *Fs) waitForJob(ctx context.Context, location string) (err error) { var status api.AsyncStatus err = json.Unmarshal(body, &status) if err != nil { - return errors.Wrapf(err, "async status result not JSON: %q", body) + return fmt.Errorf("async status result not JSON: %q: %w", body, err) } switch status.Status { case "failure": - return errors.Errorf("async operation returned %q", status.Status) + return fmt.Errorf("async operation returned %q", status.Status) case "success": return nil } time.Sleep(1 * time.Second) } - return errors.Errorf("async operation didn't complete after %v", f.ci.TimeoutOrInfinite()) + return fmt.Errorf("async operation didn't complete after %v", f.ci.TimeoutOrInfinite()) } func (f *Fs) delete(ctx context.Context, path string, hardDelete bool) (err error) { @@ -607,7 +607,7 @@ func (f *Fs) delete(ctx context.Context, path string, hardDelete bool) (err erro var info api.AsyncInfo err = json.Unmarshal(body, &info) if err != nil { - return errors.Wrapf(err, "async info result not JSON: %q", body) + return fmt.Errorf("async info result not JSON: %q: %w", body, err) } return f.waitForJob(ctx, info.HRef) } @@ -623,7 +623,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { //send request to get list of objects in this directory. info, err := f.readMetaDataForPath(ctx, root, &api.ResourceInfoRequestOptions{}) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } if len(info.Embedded.Items) != 0 { return fs.ErrorDirectoryNotEmpty @@ -683,7 +683,7 @@ func (f *Fs) copyOrMove(ctx context.Context, method, src, dst string, overwrite var info api.AsyncInfo err = json.Unmarshal(body, &info) if err != nil { - return errors.Wrapf(err, "async info result not JSON: %q", body) + return fmt.Errorf("async info result not JSON: %q: %w", body, err) } return f.waitForJob(ctx, info.HRef) } @@ -714,7 +714,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, err = f.copyOrMove(ctx, "copy", srcObj.filePath(), dstPath, false) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } return f.NewObject(ctx, remote) @@ -744,7 +744,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, err = f.copyOrMove(ctx, "move", srcObj.filePath(), dstPath, false) if err != nil { - return nil, errors.Wrap(err, "couldn't move file") + return nil, fmt.Errorf("couldn't move file: %w", err) } return f.NewObject(ctx, remote) @@ -795,7 +795,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string err = f.copyOrMove(ctx, "move", srcPath, dstPath, false) if err != nil { - return errors.Wrap(err, "couldn't move directory") + return fmt.Errorf("couldn't move directory: %w", err) } return nil } @@ -831,9 +831,9 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, } if err != nil { if unlink { - return "", errors.Wrap(err, "couldn't remove public link") + return "", fmt.Errorf("couldn't remove public link: %w", err) } - return "", errors.Wrap(err, "couldn't create public link") + return "", fmt.Errorf("couldn't create public link: %w", err) } info, err := f.readMetaDataForPath(ctx, f.filePath(remote), &api.ResourceInfoRequestOptions{}) @@ -934,7 +934,7 @@ func (o *Object) setMetaData(info *api.ResourceInfoResponse) (err error) { } t, err := time.Parse(time.RFC3339Nano, modTimeString) if err != nil { - return errors.Wrapf(err, "failed to parse modtime from %q", modTimeString) + return fmt.Errorf("failed to parse modtime from %q: %w", modTimeString, err) } o.modTime = t return nil diff --git a/backend/zoho/zoho.go b/backend/zoho/zoho.go index 117ba74e3..2132037c6 100644 --- a/backend/zoho/zoho.go +++ b/backend/zoho/zoho.go @@ -4,6 +4,7 @@ package zoho import ( "context" + "errors" "fmt" "io" "io/ioutil" @@ -14,7 +15,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/random" @@ -81,7 +81,7 @@ func init() { getSrvs := func() (authSrv, apiSrv *rest.Client, err error) { oAuthClient, _, err := oauthutil.NewClient(ctx, name, m, oauthConfig) if err != nil { - return nil, nil, errors.Wrap(err, "failed to load oAuthClient") + return nil, nil, fmt.Errorf("failed to load oAuthClient: %w", err) } authSrv = rest.NewClient(oAuthClient).SetRoot(accountsURL) apiSrv = rest.NewClient(oAuthClient).SetRoot(rootURL) @@ -100,13 +100,13 @@ func init() { // it's own custom type token, err := oauthutil.GetToken(name, m) if err != nil { - return nil, errors.Wrap(err, "failed to read token") + return nil, fmt.Errorf("failed to read token: %w", err) } if token.TokenType != "Zoho-oauthtoken" { token.TokenType = "Zoho-oauthtoken" err = oauthutil.PutToken(name, m, token, false) if err != nil { - return nil, errors.Wrap(err, "failed to configure token") + return nil, fmt.Errorf("failed to configure token: %w", err) } } @@ -478,7 +478,7 @@ OUTER: return shouldRetry(ctx, resp, err) }) if err != nil { - return found, errors.Wrap(err, "couldn't list files") + return found, fmt.Errorf("couldn't list files: %w", err) } if len(result.Items) == 0 { break @@ -670,7 +670,7 @@ func (f *Fs) upload(ctx context.Context, name string, parent string, size int64, params.Set("override-name-exist", strconv.FormatBool(true)) formReader, contentType, overhead, err := rest.MultipartUpload(ctx, in, nil, "content", name) if err != nil { - return nil, errors.Wrap(err, "failed to make multipart upload") + return nil, fmt.Errorf("failed to make multipart upload: %w", err) } contentLength := overhead + size @@ -692,7 +692,7 @@ func (f *Fs) upload(ctx context.Context, name string, parent string, size int64, return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "upload error") + return nil, fmt.Errorf("upload error: %w", err) } if len(uploadResponse.Uploads) != 1 { return nil, errors.New("upload: invalid response") @@ -774,7 +774,7 @@ func (f *Fs) deleteObject(ctx context.Context, id string) (err error) { return shouldRetry(ctx, resp, err) }) if err != nil { - return errors.Wrap(err, "delete object failed") + return fmt.Errorf("delete object failed: %w", err) } return nil } @@ -801,7 +801,7 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { err = f.deleteObject(ctx, rootID) if err != nil { - return errors.Wrap(err, "rmdir failed") + return fmt.Errorf("rmdir failed: %w", err) } f.dirCache.FlushDir(dir) return nil @@ -844,7 +844,7 @@ func (f *Fs) rename(ctx context.Context, id, name string) (item *api.Item, err e return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "rename failed") + return nil, fmt.Errorf("rename failed: %w", err) } return &result.Item, nil } @@ -897,7 +897,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "couldn't copy file") + return nil, fmt.Errorf("couldn't copy file: %w", err) } // Server acts weird some times make sure we actually got // an item @@ -911,7 +911,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, // the correct name after copy if f.opt.Enc.ToStandardName(result.Items[0].Attributes.Name) != leaf { if err = dstObject.rename(ctx, leaf); err != nil { - return nil, errors.Wrap(err, "copy: couldn't rename copied file") + return nil, fmt.Errorf("copy: couldn't rename copied file: %w", err) } } return dstObject, nil @@ -942,7 +942,7 @@ func (f *Fs) move(ctx context.Context, srcID, parentID string) (item *api.Item, return shouldRetry(ctx, resp, err) }) if err != nil { - return nil, errors.Wrap(err, "move failed") + return nil, fmt.Errorf("move failed: %w", err) } // Server acts weird some times make sure our array actually contains // a file @@ -992,7 +992,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, if needRename && needMove { tmpLeaf := "rcloneTemp" + random.String(8) if err = srcObj.rename(ctx, tmpLeaf); err != nil { - return nil, errors.Wrap(err, "move: pre move rename failed") + return nil, fmt.Errorf("move: pre move rename failed: %w", err) } } @@ -1012,7 +1012,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, // rename the leaf to its final name if needRename { if err = dstObject.rename(ctx, dstLeaf); err != nil { - return nil, errors.Wrap(err, "move: couldn't rename moved file") + return nil, fmt.Errorf("move: couldn't rename moved file: %w", err) } } return dstObject, nil @@ -1046,7 +1046,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string // do the move _, err = f.move(ctx, srcID, dstDirectoryID) if err != nil { - return errors.Wrap(err, "couldn't dir move") + return fmt.Errorf("couldn't dir move: %w", err) } // Can't copy and change name in one step so we have to check if we have @@ -1054,7 +1054,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string if srcLeaf != dstLeaf { _, err = f.rename(ctx, srcID, dstLeaf) if err != nil { - return errors.Wrap(err, "dirmove: couldn't rename moved dir") + return fmt.Errorf("dirmove: couldn't rename moved dir: %w", err) } } srcFs.dirCache.FlushDir(srcRemote) @@ -1261,7 +1261,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op // upload was successfull, need to delete old object before rename if err = o.Remove(ctx); err != nil { - return errors.Wrap(err, "failed to remove old object") + return fmt.Errorf("failed to remove old object: %w", err) } if err = o.setMetaData(info); err != nil { return err diff --git a/bin/not-in-stable.go b/bin/not-in-stable.go old mode 100755 new mode 100644 diff --git a/cmd/about/about.go b/cmd/about/about.go index 2e13fd126..fd59db672 100644 --- a/cmd/about/about.go +++ b/cmd/about/about.go @@ -3,10 +3,10 @@ package about import ( "context" "encoding/json" + "errors" "fmt" "os" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" @@ -98,11 +98,11 @@ see complete list in [documentation](https://rclone.org/overview/#optional-featu cmd.Run(false, false, command, func() error { doAbout := f.Features().About if doAbout == nil { - return errors.Errorf("%v doesn't support about", f) + return fmt.Errorf("%v doesn't support about", f) } u, err := doAbout(context.Background()) if err != nil { - return errors.Wrap(err, "About call failed") + return fmt.Errorf("About call failed: %w", err) } if u == nil { return errors.New("nil usage returned") diff --git a/cmd/backend/backend.go b/cmd/backend/backend.go index 195758991..07f7cba57 100644 --- a/cmd/backend/backend.go +++ b/cmd/backend/backend.go @@ -7,7 +7,6 @@ import ( "os" "sort" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/rc" "github.com/rclone/rclone/fs" @@ -88,14 +87,14 @@ Note to run these commands on a running backend then see default: doCommand := f.Features().Command if doCommand == nil { - return errors.Errorf("%v: doesn't support backend commands", f) + return fmt.Errorf("%v: doesn't support backend commands", f) } arg := args[2:] opt := rc.ParseOptions(options) out, err = doCommand(context.Background(), name, arg, opt) } if err != nil { - return errors.Wrapf(err, "command %q failed", name) + return fmt.Errorf("command %q failed: %w", name, err) } // Output the result @@ -121,7 +120,7 @@ Note to run these commands on a running backend then see enc.SetIndent("", "\t") err = enc.Encode(out) if err != nil { - return errors.Wrap(err, "failed to write JSON") + return fmt.Errorf("failed to write JSON: %w", err) } } return nil @@ -135,7 +134,7 @@ func showHelp(fsInfo *fs.RegInfo) error { cmds := fsInfo.CommandHelp name := fsInfo.Name if len(cmds) == 0 { - return errors.Errorf("%s backend has no commands", name) + return fmt.Errorf("%s backend has no commands", name) } fmt.Printf("## Backend commands\n\n") fmt.Printf(`Here are the commands specific to the %s backend. diff --git a/cmd/bisync/bisync_test.go b/cmd/bisync/bisync_test.go index 9f88970ed..52417b490 100644 --- a/cmd/bisync/bisync_test.go +++ b/cmd/bisync/bisync_test.go @@ -7,6 +7,7 @@ package bisync_test import ( "bytes" "context" + "errors" "flag" "fmt" "io/ioutil" @@ -36,7 +37,6 @@ import ( "github.com/rclone/rclone/lib/atexit" "github.com/rclone/rclone/lib/random" - "github.com/pkg/errors" "github.com/pmezard/go-difflib/difflib" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -541,7 +541,7 @@ func (b *bisyncTest) runTestStep(ctx context.Context, line string) (err error) { case "bisync": return b.runBisync(ctx, args[1:]) default: - return errors.Errorf("unknown command: %q", args[0]) + return fmt.Errorf("unknown command: %q", args[0]) } } @@ -635,7 +635,7 @@ func (b *bisyncTest) runBisync(ctx context.Context, args []string) (err error) { fs1 = addSubdir(b.path1, val) fs2 = addSubdir(b.path2, val) default: - return errors.Errorf("invalid bisync option %q", arg) + return fmt.Errorf("invalid bisync option %q", arg) } } @@ -793,12 +793,12 @@ func touchFiles(ctx context.Context, dateStr string, f fs.Fs, dir, glob string) date, err := time.ParseInLocation(touchDateFormat, dateStr, bisync.TZ) if err != nil { - return files, errors.Wrapf(err, "invalid date %q", dateStr) + return files, fmt.Errorf("invalid date %q: %w", dateStr, err) } matcher, firstErr := filter.GlobToRegexp(glob, false) if firstErr != nil { - return files, errors.Errorf("invalid glob %q", glob) + return files, fmt.Errorf("invalid glob %q", glob) } entries, firstErr := f.List(ctx, "") diff --git a/cmd/bisync/cmd.go b/cmd/bisync/cmd.go index fbcb27d11..42b6489bf 100644 --- a/cmd/bisync/cmd.go +++ b/cmd/bisync/cmd.go @@ -6,6 +6,8 @@ import ( "context" "crypto/md5" "encoding/hex" + "errors" + "fmt" "io" "io/ioutil" "os" @@ -21,7 +23,6 @@ import ( "github.com/rclone/rclone/fs/filter" "github.com/rclone/rclone/fs/hash" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -82,7 +83,7 @@ func (x *CheckSyncMode) Set(s string) error { case "only": *x = CheckSyncOnly default: - return errors.Errorf("unknown check-sync mode for bisync: %q", s) + return fmt.Errorf("unknown check-sync mode for bisync: %q", s) } return nil } @@ -184,7 +185,7 @@ func (opt *Options) applyFilters(ctx context.Context) (context.Context, error) { f, err := os.Open(filtersFile) if err != nil { - return ctx, errors.Errorf("specified filters file does not exist: %s", filtersFile) + return ctx, fmt.Errorf("specified filters file does not exist: %s", filtersFile) } fs.Infof(nil, "Using filters file %s", filtersFile) @@ -199,11 +200,11 @@ func (opt *Options) applyFilters(ctx context.Context) (context.Context, error) { hashFile := filtersFile + ".md5" wantHash, err := ioutil.ReadFile(hashFile) if err != nil && !opt.Resync { - return ctx, errors.Errorf("filters file md5 hash not found (must run --resync): %s", filtersFile) + return ctx, fmt.Errorf("filters file md5 hash not found (must run --resync): %s", filtersFile) } if gotHash != string(wantHash) && !opt.Resync { - return ctx, errors.Errorf("filters file has changed (must run --resync): %s", filtersFile) + return ctx, fmt.Errorf("filters file has changed (must run --resync): %s", filtersFile) } if opt.Resync { @@ -218,7 +219,7 @@ func (opt *Options) applyFilters(ctx context.Context) (context.Context, error) { filterOpt.FilterFrom = append([]string{filtersFile}, filterOpt.FilterFrom...) newFilter, err := filter.NewFilter(&filterOpt) if err != nil { - return ctx, errors.Wrapf(err, "invalid filters file: %s", filtersFile) + return ctx, fmt.Errorf("invalid filters file: %s: %w", filtersFile, err) } return filter.ReplaceConfig(ctx, newFilter), nil diff --git a/cmd/bisync/deltas.go b/cmd/bisync/deltas.go index 0e09f15f2..ee66980c4 100644 --- a/cmd/bisync/deltas.go +++ b/cmd/bisync/deltas.go @@ -4,10 +4,10 @@ package bisync import ( "context" + "fmt" "path/filepath" "sort" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/bisync/bilib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/operations" @@ -201,7 +201,7 @@ func (b *bisyncRun) applyDeltas(ctx context.Context, ds1, ds2 *deltaSet) (change b.indent("!WARNING", file, "New or changed in both paths") b.indent("!Path1", p1+"..path1", "Renaming Path1 copy") if err = operations.MoveFile(ctxMove, b.fs1, b.fs1, file+"..path1", file); err != nil { - err = errors.Wrapf(err, "path1 rename failed for %s", p1) + err = fmt.Errorf("path1 rename failed for %s: %w", p1, err) b.critical = true return } @@ -210,7 +210,7 @@ func (b *bisyncRun) applyDeltas(ctx context.Context, ds1, ds2 *deltaSet) (change b.indent("!Path2", p2+"..path2", "Renaming Path2 copy") if err = operations.MoveFile(ctxMove, b.fs2, b.fs2, file+"..path2", file); err != nil { - err = errors.Wrapf(err, "path2 rename failed for %s", file) + err = fmt.Errorf("path2 rename failed for %s: %w", file, err) return } b.indent("!Path2", p1+"..path2", "Queue copy to Path1") diff --git a/cmd/bisync/listing.go b/cmd/bisync/listing.go index 3b08bc482..610823c64 100644 --- a/cmd/bisync/listing.go +++ b/cmd/bisync/listing.go @@ -14,7 +14,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/walk" @@ -246,7 +245,7 @@ func parseHash(str string) (string, string, error) { return name, val, nil } } - return "", "", errors.Errorf("invalid hash %q", str) + return "", "", fmt.Errorf("invalid hash %q", str) } // makeListing will produce listing from directory tree and write it to a file @@ -301,5 +300,5 @@ func (b *bisyncRun) checkListing(ls *fileList, listing, msg string) error { } fs.Errorf(nil, "Empty %s listing. Cannot sync to an empty directory: %s", msg, listing) b.critical = true - return errors.Errorf("empty %s listing: %s", msg, listing) + return fmt.Errorf("empty %s listing: %s", msg, listing) } diff --git a/cmd/bisync/operations.go b/cmd/bisync/operations.go index e7d853cd1..d32153edc 100644 --- a/cmd/bisync/operations.go +++ b/cmd/bisync/operations.go @@ -5,13 +5,14 @@ package bisync import ( "context" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" "strconv" gosync "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/bisync/bilib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/filter" @@ -60,10 +61,10 @@ func Bisync(ctx context.Context, fs1, fs2 fs.Fs, optArg *Options) (err error) { } if b.workDir, err = filepath.Abs(opt.Workdir); err != nil { - return errors.Wrap(err, "failed to make workdir absolute") + return fmt.Errorf("failed to make workdir absolute: %w", err) } if err = os.MkdirAll(b.workDir, os.ModePerm); err != nil { - return errors.Wrap(err, "failed to create workdir") + return fmt.Errorf("failed to create workdir: %w", err) } // Produce a unique name for the sync operation @@ -76,12 +77,12 @@ func Bisync(ctx context.Context, fs1, fs2 fs.Fs, optArg *Options) (err error) { if !opt.DryRun { lockFile = b.basePath + ".lck" if bilib.FileExists(lockFile) { - return errors.Errorf("prior lock file found: %s", lockFile) + return fmt.Errorf("prior lock file found: %s", lockFile) } pidStr := []byte(strconv.Itoa(os.Getpid())) if err = ioutil.WriteFile(lockFile, pidStr, bilib.PermSecure); err != nil { - return errors.Wrapf(err, "cannot create lock file: %s", lockFile) + return fmt.Errorf("cannot create lock file: %s: %w", lockFile, err) } fs.Debugf(nil, "Lock file created: %s", lockFile) } @@ -394,11 +395,11 @@ func (b *bisyncRun) resync(octx, fctx context.Context, listing1, listing2 string func (b *bisyncRun) checkSync(listing1, listing2 string) error { files1, err := b.loadListing(listing1) if err != nil { - return errors.Wrap(err, "cannot read prior listing of Path1") + return fmt.Errorf("cannot read prior listing of Path1: %w", err) } files2, err := b.loadListing(listing2) if err != nil { - return errors.Wrap(err, "cannot read prior listing of Path2") + return fmt.Errorf("cannot read prior listing of Path2: %w", err) } ok := true diff --git a/cmd/bisync/rc.go b/cmd/bisync/rc.go index fe74af052..04f723f03 100644 --- a/cmd/bisync/rc.go +++ b/cmd/bisync/rc.go @@ -2,9 +2,9 @@ package bisync import ( "context" + "errors" "log" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/bisync/bilib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" diff --git a/cmd/cachestats/cachestats.go b/cmd/cachestats/cachestats.go index 1daaed37b..16a1398d3 100644 --- a/cmd/cachestats/cachestats.go +++ b/cmd/cachestats/cachestats.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/cache" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" @@ -39,7 +38,7 @@ Print cache stats for a remote in JSON format fsCache, ok = unwrap().(*cache.Fs) } if !ok { - return errors.Errorf("%s: is not a cache remote", fsrc.Name()) + return fmt.Errorf("%s: is not a cache remote", fsrc.Name()) } } m, err := fsCache.Stats() diff --git a/cmd/cmd.go b/cmd/cmd.go index 2de68715a..a9f0e910f 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -8,6 +8,7 @@ package cmd import ( "context" + "errors" "fmt" "log" "os" @@ -21,7 +22,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/cache" @@ -117,7 +117,7 @@ func newFsFileAddFilter(remote string) (fs.Fs, string) { f, fileName := NewFsFile(remote) if fileName != "" { if !fi.InActive() { - err := errors.Errorf("Can't limit to single files when using filters: %v", remote) + err := fmt.Errorf("Can't limit to single files when using filters: %v", remote) err = fs.CountError(err) log.Fatalf(err.Error()) } @@ -478,16 +478,14 @@ func resolveExitCode(err error) { os.Exit(exitcode.Success) } - _, unwrapped := fserrors.Cause(err) - switch { - case unwrapped == fs.ErrorDirNotFound: + case errors.Is(err, fs.ErrorDirNotFound): os.Exit(exitcode.DirNotFound) - case unwrapped == fs.ErrorObjectNotFound: + case errors.Is(err, fs.ErrorObjectNotFound): os.Exit(exitcode.FileNotFound) - case unwrapped == errorUncategorized: + case errors.Is(err, errorUncategorized): os.Exit(exitcode.UncategorizedError) - case unwrapped == accounting.ErrorMaxTransferLimitReached: + case errors.Is(err, accounting.ErrorMaxTransferLimitReached): os.Exit(exitcode.TransferExceeded) case fserrors.ShouldRetry(err): os.Exit(exitcode.RetryError) diff --git a/cmd/cmount/fs.go b/cmd/cmount/fs.go index 6545c058d..d627a9829 100644 --- a/cmd/cmount/fs.go +++ b/cmd/cmount/fs.go @@ -14,9 +14,9 @@ import ( "time" "github.com/billziss-gh/cgofuse/fuse" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/log" "github.com/rclone/rclone/vfs" ) @@ -569,7 +569,8 @@ func translateError(err error) (errc int) { if err == nil { return 0 } - switch errors.Cause(err) { + _, uErr := fserrors.Cause(err) + switch uErr { case vfs.OK: return 0 case vfs.ENOENT, fs.ErrorDirNotFound, fs.ErrorObjectNotFound: diff --git a/cmd/cmount/mount.go b/cmd/cmount/mount.go index 3070763ba..42b1c51ab 100644 --- a/cmd/cmount/mount.go +++ b/cmd/cmount/mount.go @@ -10,6 +10,7 @@ package cmount import ( + "errors" "fmt" "os" "runtime" @@ -18,7 +19,6 @@ import ( "time" "github.com/billziss-gh/cgofuse/fuse" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/atexit" @@ -176,7 +176,7 @@ func mount(VFS *vfs.VFS, mountPath string, opt *mountlib.Options) (<-chan error, go func() { defer func() { if r := recover(); r != nil { - errChan <- errors.Errorf("mount failed: %v", r) + errChan <- fmt.Errorf("mount failed: %v", r) } }() var err error @@ -224,7 +224,7 @@ func mount(VFS *vfs.VFS, mountPath string, opt *mountlib.Options) (<-chan error, // system didn't blow up before starting select { case err := <-errChan: - err = errors.Wrap(err, "mount stopped before calling Init") + err = fmt.Errorf("mount stopped before calling Init: %w", err) return nil, nil, err case <-fsys.ready: } diff --git a/cmd/cmount/mount_brew.go b/cmd/cmount/mount_brew.go index e30f4dab6..26531ff7a 100644 --- a/cmd/cmount/mount_brew.go +++ b/cmd/cmount/mount_brew.go @@ -7,7 +7,8 @@ package cmount import ( - "github.com/pkg/errors" + "errors" + "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/vfs" ) diff --git a/cmd/cmount/mountpoint_other.go b/cmd/cmount/mountpoint_other.go index aa1f46336..1061d096a 100644 --- a/cmd/cmount/mountpoint_other.go +++ b/cmd/cmount/mountpoint_other.go @@ -4,16 +4,17 @@ package cmount import ( + "errors" + "fmt" "os" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" ) func getMountpoint(mountPath string, opt *mountlib.Options) (string, error) { fi, err := os.Stat(mountPath) if err != nil { - return "", errors.Wrap(err, "failed to retrieve mount path information") + return "", fmt.Errorf("failed to retrieve mount path information: %w", err) } if !fi.IsDir() { return "", errors.New("mount path is not a directory") diff --git a/cmd/cmount/mountpoint_windows.go b/cmd/cmount/mountpoint_windows.go index d70bc30af..8a06c88b4 100644 --- a/cmd/cmount/mountpoint_windows.go +++ b/cmd/cmount/mountpoint_windows.go @@ -4,11 +4,12 @@ package cmount import ( + "fmt" "os" + "errors" "path/filepath" "regexp" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/file" @@ -100,7 +101,7 @@ func handleLocalMountpath(mountpath string, opt *mountlib.Options) (string, erro if _, err := os.Stat(mountpath); err == nil { return "", errors.New("mountpoint path already exists: " + mountpath) } else if !os.IsNotExist(err) { - return "", errors.Wrap(err, "failed to retrieve mountpoint path information") + return "", fmt.Errorf("failed to retrieve mountpoint path information: %w", err) } if isDriveRootPath(mountpath) { // Assume intention with "X:\" was "X:" mountpath = mountpath[:len(mountpath)-1] // WinFsp needs drive mountpoints without trailing path separator @@ -115,14 +116,14 @@ func handleLocalMountpath(mountpath string, opt *mountlib.Options) (string, erro } var err error if mountpath, err = filepath.Abs(mountpath); err != nil { // Ensures parent is found but also more informative log messages - return "", errors.Wrap(err, "mountpoint path is not valid: "+mountpath) + return "", fmt.Errorf("mountpoint path is not valid: %s: %w", mountpath, err) } parent := filepath.Join(mountpath, "..") if _, err = os.Stat(parent); err != nil { if os.IsNotExist(err) { return "", errors.New("parent of mountpoint directory does not exist: " + parent) } - return "", errors.Wrap(err, "failed to retrieve mountpoint directory parent information") + return "", fmt.Errorf("failed to retrieve mountpoint directory parent information: %w", err) } } return mountpath, nil diff --git a/cmd/config/config.go b/cmd/config/config.go index 1c9d31ed5..96734e552 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -3,12 +3,12 @@ package config import ( "context" "encoding/json" + "errors" "fmt" "os" "sort" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -398,11 +398,11 @@ To reconnect use "rclone config reconnect". f := cmd.NewFsSrc(args) doDisconnect := f.Features().Disconnect if doDisconnect == nil { - return errors.Errorf("%v doesn't support Disconnect", f) + return fmt.Errorf("%v doesn't support Disconnect", f) } err := doDisconnect(context.Background()) if err != nil { - return errors.Wrap(err, "Disconnect call failed") + return fmt.Errorf("Disconnect call failed: %w", err) } return nil }, @@ -428,11 +428,11 @@ system. f := cmd.NewFsSrc(args) doUserInfo := f.Features().UserInfo if doUserInfo == nil { - return errors.Errorf("%v doesn't support UserInfo", f) + return fmt.Errorf("%v doesn't support UserInfo", f) } u, err := doUserInfo(context.Background()) if err != nil { - return errors.Wrap(err, "UserInfo call failed") + return fmt.Errorf("UserInfo call failed: %w", err) } if jsonOutput { out := json.NewEncoder(os.Stdout) diff --git a/cmd/cryptcheck/cryptcheck.go b/cmd/cryptcheck/cryptcheck.go index b803beb5d..7ef0e86a4 100644 --- a/cmd/cryptcheck/cryptcheck.go +++ b/cmd/cryptcheck/cryptcheck.go @@ -2,8 +2,8 @@ package cryptcheck import ( "context" + "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/check" @@ -60,13 +60,13 @@ func cryptCheck(ctx context.Context, fdst, fsrc fs.Fs) error { // Check to see fcrypt is a crypt fcrypt, ok := fdst.(*crypt.Fs) if !ok { - return errors.Errorf("%s:%s is not a crypt remote", fdst.Name(), fdst.Root()) + return fmt.Errorf("%s:%s is not a crypt remote", fdst.Name(), fdst.Root()) } // Find a hash to use funderlying := fcrypt.UnWrap() hashType := funderlying.Hashes().GetOne() if hashType == hash.None { - return errors.Errorf("%s:%s does not support any hashes", funderlying.Name(), funderlying.Root()) + return fmt.Errorf("%s:%s does not support any hashes", funderlying.Name(), funderlying.Root()) } fs.Infof(nil, "Using %v for hash comparisons", hashType) @@ -85,20 +85,20 @@ func cryptCheck(ctx context.Context, fdst, fsrc fs.Fs) error { underlyingDst := cryptDst.UnWrap() underlyingHash, err := underlyingDst.Hash(ctx, hashType) if err != nil { - return true, false, errors.Wrapf(err, "error reading hash from underlying %v", underlyingDst) + return true, false, fmt.Errorf("error reading hash from underlying %v: %w", underlyingDst, err) } if underlyingHash == "" { return false, true, nil } cryptHash, err := fcrypt.ComputeHash(ctx, cryptDst, src, hashType) if err != nil { - return true, false, errors.Wrap(err, "error computing hash") + return true, false, fmt.Errorf("error computing hash: %w", err) } if cryptHash == "" { return false, true, nil } if cryptHash != underlyingHash { - err = errors.Errorf("hashes differ (%s:%s) %q vs (%s:%s) %q", fdst.Name(), fdst.Root(), cryptHash, fsrc.Name(), fsrc.Root(), underlyingHash) + err = fmt.Errorf("hashes differ (%s:%s) %q vs (%s:%s) %q", fdst.Name(), fdst.Root(), cryptHash, fsrc.Name(), fsrc.Root(), underlyingHash) fs.Errorf(src, err.Error()) return true, false, nil } diff --git a/cmd/deletefile/deletefile.go b/cmd/deletefile/deletefile.go index 9e8731aa4..88750c75e 100644 --- a/cmd/deletefile/deletefile.go +++ b/cmd/deletefile/deletefile.go @@ -2,8 +2,8 @@ package deletefile import ( "context" + "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs/operations" "github.com/spf13/cobra" @@ -26,7 +26,7 @@ it will always be removed. fs, fileName := cmd.NewFsFile(args[0]) cmd.Run(true, false, command, func() error { if fileName == "" { - return errors.Errorf("%s is a directory or doesn't exist", args[0]) + return fmt.Errorf("%s is a directory or doesn't exist", args[0]) } fileObj, err := fs.NewObject(context.Background(), fileName) if err != nil { diff --git a/cmd/hashsum/hashsum.go b/cmd/hashsum/hashsum.go index 509af664c..3988596a4 100644 --- a/cmd/hashsum/hashsum.go +++ b/cmd/hashsum/hashsum.go @@ -2,10 +2,10 @@ package hashsum import ( "context" + "errors" "fmt" "os" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" @@ -41,7 +41,7 @@ func AddHashFlags(cmdFlags *pflag.FlagSet) { func GetHashsumOutput(filename string) (out *os.File, close func(), err error) { out, err = os.Create(filename) if err != nil { - err = errors.Wrapf(err, "Failed to open output file %v", filename) + err = fmt.Errorf("Failed to open output file %v: %w", filename, err) return nil, nil, err } diff --git a/cmd/lsf/lsf.go b/cmd/lsf/lsf.go index 6ce79a34a..a461a5c9c 100644 --- a/cmd/lsf/lsf.go +++ b/cmd/lsf/lsf.go @@ -6,7 +6,6 @@ import ( "io" "os" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/ls/lshelp" "github.com/rclone/rclone/fs" @@ -200,7 +199,7 @@ func Lsf(ctx context.Context, fsrc fs.Fs, out io.Writer) error { case 'T': list.AddTier() default: - return errors.Errorf("Unknown format character %q", char) + return fmt.Errorf("Unknown format character %q", char) } } diff --git a/cmd/lsjson/lsjson.go b/cmd/lsjson/lsjson.go index c2bb8aace..47bafa4e3 100644 --- a/cmd/lsjson/lsjson.go +++ b/cmd/lsjson/lsjson.go @@ -6,7 +6,6 @@ import ( "fmt" "os" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/ls/lshelp" "github.com/rclone/rclone/fs" @@ -125,11 +124,11 @@ can be processed line by line as each item is written one to a line. } out, err := json.MarshalIndent(item, "", "\t") if err != nil { - return errors.Wrap(err, "failed to marshal list object") + return fmt.Errorf("failed to marshal list object: %w", err) } _, err = os.Stdout.Write(out) if err != nil { - return errors.Wrap(err, "failed to write to output") + return fmt.Errorf("failed to write to output: %w", err) } fmt.Println() } else { @@ -138,7 +137,7 @@ can be processed line by line as each item is written one to a line. err := operations.ListJSON(context.Background(), fsrc, remote, &opt, func(item *operations.ListJSONItem) error { out, err := json.Marshal(item) if err != nil { - return errors.Wrap(err, "failed to marshal list object") + return fmt.Errorf("failed to marshal list object: %w", err) } if first { first = false @@ -147,7 +146,7 @@ can be processed line by line as each item is written one to a line. } _, err = os.Stdout.Write(out) if err != nil { - return errors.Wrap(err, "failed to write to output") + return fmt.Errorf("failed to write to output: %w", err) } return nil }) diff --git a/cmd/mount/dir.go b/cmd/mount/dir.go index 9da7a1a64..2acb0c48e 100644 --- a/cmd/mount/dir.go +++ b/cmd/mount/dir.go @@ -5,13 +5,13 @@ package mount import ( "context" + "fmt" "io" "os" "time" "bazil.org/fuse" fusefs "bazil.org/fuse/fs" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/log" @@ -199,7 +199,7 @@ func (d *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fusefs defer log.Trace(d, "oldName=%q, newName=%q, newDir=%+v", req.OldName, req.NewName, newDir)("err=%v", &err) destDir, ok := newDir.(*Dir) if !ok { - return errors.Errorf("Unknown Dir type %T", newDir) + return fmt.Errorf("Unknown Dir type %T", newDir) } err = d.Dir.Rename(req.OldName, req.NewName, destDir.Dir) diff --git a/cmd/mount/fs.go b/cmd/mount/fs.go index 0ecd4aaa4..8e9dad751 100644 --- a/cmd/mount/fs.go +++ b/cmd/mount/fs.go @@ -11,9 +11,9 @@ import ( "bazil.org/fuse" fusefs "bazil.org/fuse/fs" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/log" "github.com/rclone/rclone/vfs" ) @@ -77,7 +77,8 @@ func translateError(err error) error { if err == nil { return nil } - switch errors.Cause(err) { + _, uErr := fserrors.Cause(err) + switch uErr { case vfs.OK: return nil case vfs.ENOENT, fs.ErrorDirNotFound, fs.ErrorObjectNotFound: diff --git a/cmd/mount2/fs.go b/cmd/mount2/fs.go index 94e70a60c..0ab28f05a 100644 --- a/cmd/mount2/fs.go +++ b/cmd/mount2/fs.go @@ -10,9 +10,9 @@ import ( "syscall" "github.com/hanwen/go-fuse/v2/fuse" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" + "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/log" "github.com/rclone/rclone/vfs" ) @@ -104,7 +104,8 @@ func translateError(err error) syscall.Errno { if err == nil { return 0 } - switch errors.Cause(err) { + _, uErr := fserrors.Cause(err) + switch uErr { case vfs.OK: return 0 case vfs.ENOENT, fs.ErrorDirNotFound, fs.ErrorObjectNotFound: diff --git a/cmd/mountlib/check_linux.go b/cmd/mountlib/check_linux.go index bad2dee8d..3cdb34690 100644 --- a/cmd/mountlib/check_linux.go +++ b/cmd/mountlib/check_linux.go @@ -4,12 +4,13 @@ package mountlib import ( + "errors" + "fmt" "path/filepath" "strings" "time" "github.com/artyom/mtab" - "github.com/pkg/errors" ) const ( @@ -25,16 +26,16 @@ func CheckMountEmpty(mountpoint string) error { mountpointAbs, err := filepath.Abs(mountpoint) if err != nil { - return errors.Wrapf(err, "cannot get absolute path: %s", mountpoint) + return fmt.Errorf("cannot get absolute path: %s: %w", mountpoint, err) } entries, err := mtab.Entries(mtabPath) if err != nil { - return errors.Wrapf(err, "cannot read %s", mtabPath) + return fmt.Errorf("cannot read %s: %w", mtabPath, err) } for _, entry := range entries { if entry.Dir == mountpointAbs && entry.Type != "autofs" { - return errors.Errorf(msg, mountpointAbs) + return fmt.Errorf(msg, mountpointAbs) } } return nil @@ -45,11 +46,11 @@ func CheckMountEmpty(mountpoint string) error { func CheckMountReady(mountpoint string) error { mountpointAbs, err := filepath.Abs(mountpoint) if err != nil { - return errors.Wrapf(err, "cannot get absolute path: %s", mountpoint) + return fmt.Errorf("cannot get absolute path: %s: %w", mountpoint, err) } entries, err := mtab.Entries(mtabPath) if err != nil { - return errors.Wrapf(err, "cannot read %s", mtabPath) + return fmt.Errorf("cannot read %s: %w", mtabPath, err) } for _, entry := range entries { if entry.Dir == mountpointAbs && strings.Contains(entry.Type, "rclone") { diff --git a/cmd/mountlib/check_other.go b/cmd/mountlib/check_other.go index cfcbd133c..0b7eeede7 100644 --- a/cmd/mountlib/check_other.go +++ b/cmd/mountlib/check_other.go @@ -4,11 +4,11 @@ package mountlib import ( + "fmt" "io" "os" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -17,7 +17,7 @@ import ( func CheckMountEmpty(mountpoint string) error { fp, err := os.Open(mountpoint) if err != nil { - return errors.Wrapf(err, "Can not open: %s", mountpoint) + return fmt.Errorf("Can not open: %s: %w", mountpoint, err) } defer fs.CheckClose(fp, &err) @@ -28,9 +28,9 @@ func CheckMountEmpty(mountpoint string) error { const msg = "Directory is not empty, use --allow-non-empty to mount anyway: %s" if err == nil { - return errors.Errorf(msg, mountpoint) + return fmt.Errorf(msg, mountpoint) } - return errors.Wrapf(err, msg, mountpoint) + return fmt.Errorf(msg+": %w", mountpoint, err) } // CheckMountReady should check if mountpoint is mounted by rclone. diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index 3a20540ea..60d2661e7 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -2,6 +2,7 @@ package mountlib import ( "context" + "fmt" "log" "os" "runtime" @@ -21,7 +22,6 @@ import ( "github.com/rclone/rclone/vfs/vfsflags" sysdnotify "github.com/iguanesolutions/go-systemd/v5/notify" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -248,7 +248,7 @@ func (m *MountPoint) Mount() (daemon *os.Process, err error) { m.ErrChan, m.UnmountFn, err = m.MountFn(m.VFS, m.MountPoint, &m.MountOpt) if err != nil { - return nil, errors.Wrap(err, "failed to mount FUSE fs") + return nil, fmt.Errorf("failed to mount FUSE fs: %w", err) } return nil, nil } @@ -277,7 +277,7 @@ func (m *MountPoint) Wait() error { // Notify systemd if err := sysdnotify.Ready(); err != nil { - return errors.Wrap(err, "failed to notify systemd") + return fmt.Errorf("failed to notify systemd: %w", err) } // Reload VFS cache on SIGHUP @@ -305,7 +305,7 @@ func (m *MountPoint) Wait() error { finalise() if err != nil { - return errors.Wrap(err, "failed to umount FUSE fs") + return fmt.Errorf("failed to umount FUSE fs: %w", err) } return nil } diff --git a/cmd/mountlib/rc.go b/cmd/mountlib/rc.go index 1f613da38..2262ecfa8 100644 --- a/cmd/mountlib/rc.go +++ b/cmd/mountlib/rc.go @@ -2,12 +2,12 @@ package mountlib import ( "context" + "errors" "log" "sort" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/vfs" diff --git a/cmd/mountlib/utils.go b/cmd/mountlib/utils.go index 510bd87aa..673903317 100644 --- a/cmd/mountlib/utils.go +++ b/cmd/mountlib/utils.go @@ -1,11 +1,11 @@ package mountlib import ( + "fmt" "path/filepath" "runtime" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -42,7 +42,7 @@ func (m *MountPoint) CheckOverlap() error { mountpointAbs := absPath(m.MountPoint) if strings.HasPrefix(rootAbs, mountpointAbs) || strings.HasPrefix(mountpointAbs, rootAbs) { const msg = "mount point %q and directory to be mounted %q mustn't overlap" - return errors.Errorf(msg, m.MountPoint, m.Fs.Root()) + return fmt.Errorf(msg, m.MountPoint, m.Fs.Root()) } return nil } diff --git a/cmd/ncdu/ncdu.go b/cmd/ncdu/ncdu.go index 38f97d659..2eec715b0 100644 --- a/cmd/ncdu/ncdu.go +++ b/cmd/ncdu/ncdu.go @@ -16,7 +16,6 @@ import ( "github.com/atotto/clipboard" runewidth "github.com/mattn/go-runewidth" termbox "github.com/nsf/termbox-go" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/ncdu/scan" "github.com/rclone/rclone/fs" @@ -314,7 +313,7 @@ func (u *UI) Draw() error { // Plot err := termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) if err != nil { - return errors.Wrap(err, "failed to clear screen") + return fmt.Errorf("failed to clear screen: %w", err) } // Header line @@ -432,7 +431,7 @@ func (u *UI) Draw() error { } err = termbox.Flush() if err != nil { - return errors.Wrap(err, "failed to flush screen") + return fmt.Errorf("failed to flush screen: %w", err) } return nil } @@ -742,7 +741,7 @@ func NewUI(f fs.Fs) *UI { func (u *UI) Show() error { err := termbox.Init() if err != nil { - return errors.Wrap(err, "termbox init") + return fmt.Errorf("termbox init: %w", err) } defer termbox.Close() @@ -766,7 +765,7 @@ outer: //Reset() err := u.Draw() if err != nil { - return errors.Wrap(err, "draw failed") + return fmt.Errorf("draw failed: %w", err) } var root *scan.Dir select { @@ -775,7 +774,7 @@ outer: u.setCurrentDir(root) case err := <-errChan: if err != nil { - return errors.Wrap(err, "ncdu directory listing") + return fmt.Errorf("ncdu directory listing: %w", err) } u.listing = false case <-updated: diff --git a/cmd/ncdu/scan/scan.go b/cmd/ncdu/scan/scan.go index 77b15ff8e..292e78426 100644 --- a/cmd/ncdu/scan/scan.go +++ b/cmd/ncdu/scan/scan.go @@ -3,10 +3,10 @@ package scan import ( "context" + "fmt" "path" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/walk" ) @@ -185,7 +185,7 @@ func Scan(ctx context.Context, f fs.Fs) (chan *Dir, chan error, chan struct{}) { var ok bool parent, ok = parents[parentPath] if !ok { - errChan <- errors.Errorf("couldn't find parent for %q", dirPath) + errChan <- fmt.Errorf("couldn't find parent for %q", dirPath) } } d := newDir(parent, dirPath, entries, err) @@ -202,7 +202,7 @@ func Scan(ctx context.Context, f fs.Fs) (chan *Dir, chan error, chan struct{}) { return nil }) if err != nil { - errChan <- errors.Wrap(err, "ncdu listing failed") + errChan <- fmt.Errorf("ncdu listing failed: %w", err) } errChan <- nil }() diff --git a/cmd/rc/rc.go b/cmd/rc/rc.go index 92ae1fdf9..c2eb7a24f 100644 --- a/cmd/rc/rc.go +++ b/cmd/rc/rc.go @@ -4,13 +4,13 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" "os" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" @@ -163,16 +163,16 @@ func doCall(ctx context.Context, path string, in rc.Params) (out rc.Params, err if loopback { call := rc.Calls.Get(path) if call == nil { - return nil, errors.Errorf("method %q not found", path) + return nil, fmt.Errorf("method %q not found", path) } _, out, err := jobs.NewJob(ctx, call.Fn, in) if err != nil { - return nil, errors.Wrap(err, "loopback call failed") + return nil, fmt.Errorf("loopback call failed: %w", err) } // Reshape (serialize then deserialize) the data so it is in the form expected err = rc.Reshape(&out, out) if err != nil { - return nil, errors.Wrap(err, "loopback reshape failed") + return nil, fmt.Errorf("loopback reshape failed: %w", err) } return out, nil } @@ -182,12 +182,12 @@ func doCall(ctx context.Context, path string, in rc.Params) (out rc.Params, err url += path data, err := json.Marshal(in) if err != nil { - return nil, errors.Wrap(err, "failed to encode JSON") + return nil, fmt.Errorf("failed to encode JSON: %w", err) } req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(data)) if err != nil { - return nil, errors.Wrap(err, "failed to make request") + return nil, fmt.Errorf("failed to make request: %w", err) } req.Header.Set("Content-Type", "application/json") @@ -197,7 +197,7 @@ func doCall(ctx context.Context, path string, in rc.Params) (out rc.Params, err resp, err := client.Do(req) if err != nil { - return nil, errors.Wrap(err, "connection failed") + return nil, fmt.Errorf("connection failed: %w", err) } defer fs.CheckClose(resp.Body, &err) @@ -211,19 +211,19 @@ func doCall(ctx context.Context, path string, in rc.Params) (out rc.Params, err bodyString = err.Error() } bodyString = strings.TrimSpace(bodyString) - return nil, errors.Errorf("Failed to read rc response: %s: %s", resp.Status, bodyString) + return nil, fmt.Errorf("Failed to read rc response: %s: %s", resp.Status, bodyString) } // Parse output out = make(rc.Params) err = json.NewDecoder(resp.Body).Decode(&out) if err != nil { - return nil, errors.Wrap(err, "failed to decode JSON") + return nil, fmt.Errorf("failed to decode JSON: %w", err) } // Check we got 200 OK if resp.StatusCode != http.StatusOK { - err = errors.Errorf("operation %q failed: %v", path, out["error"]) + err = fmt.Errorf("operation %q failed: %v", path, out["error"]) } return out, err @@ -240,7 +240,7 @@ func run(ctx context.Context, args []string) (err error) { for _, param := range params { equals := strings.IndexRune(param, '=') if equals < 0 { - return errors.Errorf("no '=' found in parameter %q", param) + return fmt.Errorf("no '=' found in parameter %q", param) } key, value := param[:equals], param[equals+1:] in[key] = value @@ -251,7 +251,7 @@ func run(ctx context.Context, args []string) (err error) { } err = json.Unmarshal([]byte(jsonInput), &in) if err != nil { - return errors.Wrap(err, "bad --json input") + return fmt.Errorf("bad --json input: %w", err) } } if len(options) > 0 { @@ -268,7 +268,7 @@ func run(ctx context.Context, args []string) (err error) { if out != nil && !noOutput { err := rc.WriteJSON(os.Stdout, out) if err != nil { - return errors.Wrap(err, "failed to output JSON") + return fmt.Errorf("failed to output JSON: %w", err) } } @@ -279,7 +279,7 @@ func run(ctx context.Context, args []string) (err error) { func list(ctx context.Context) error { list, err := doCall(ctx, "rc/list", nil) if err != nil { - return errors.Wrap(err, "failed to list") + return fmt.Errorf("failed to list: %w", err) } commands, ok := list["commands"].([]interface{}) if !ok { diff --git a/cmd/selfupdate/selfupdate.go b/cmd/selfupdate/selfupdate.go index c87561c45..f15bce83c 100644 --- a/cmd/selfupdate/selfupdate.go +++ b/cmd/selfupdate/selfupdate.go @@ -10,6 +10,7 @@ import ( "context" "crypto/sha256" "encoding/hex" + "errors" "fmt" "io" "io/ioutil" @@ -22,7 +23,6 @@ import ( "runtime" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/cmount" "github.com/rclone/rclone/fs" @@ -125,7 +125,7 @@ func GetVersion(ctx context.Context, beta bool, version string) (newVersion, sit if strings.Count(newVersion, ".") == 1 { html, err := downloadFile(ctx, siteURL) if err != nil { - return "", siteURL, errors.Wrap(err, "failed to get list of releases") + return "", siteURL, fmt.Errorf("failed to get list of releases: %w", err) } reSubver := fmt.Sprintf(`href="\./%s\.\d+/"`, regexp.QuoteMeta(newVersion)) allSubvers := regexp.MustCompile(reSubver).FindAllString(string(html), -1) @@ -154,7 +154,7 @@ func InstallUpdate(ctx context.Context, opt *Options) error { newVersion, siteURL, err := GetVersion(ctx, opt.Beta, opt.Version) if err != nil { - return errors.Wrap(err, "unable to detect new version") + return fmt.Errorf("unable to detect new version: %w", err) } oldVersion := fs.Version @@ -179,7 +179,7 @@ func InstallUpdate(ctx context.Context, opt *Options) error { // Get the current executable path executable, err := os.Executable() if err != nil { - return errors.Wrap(err, "unable to find executable") + return fmt.Errorf("unable to find executable: %w", err) } targetFile := opt.Output @@ -217,7 +217,7 @@ func InstallUpdate(ctx context.Context, opt *Options) error { // Download the update as a temporary file err = downloadUpdate(ctx, opt.Beta, newVersion, siteURL, newFile, "zip") if err != nil { - return errors.Wrap(err, "failed to update rclone") + return fmt.Errorf("failed to update rclone: %w", err) } err = replaceExecutable(targetFile, newFile, savedFile) @@ -230,7 +230,7 @@ func InstallUpdate(ctx context.Context, opt *Options) error { func installPackage(ctx context.Context, beta bool, version, siteURL, packageFormat string) error { tempFile, err := ioutil.TempFile("", "rclone.*."+packageFormat) if err != nil { - return errors.Wrap(err, "unable to write temporary package") + return fmt.Errorf("unable to write temporary package: %w", err) } packageFile := tempFile.Name() _ = tempFile.Close() @@ -262,7 +262,7 @@ func replaceExecutable(targetFile, newFile, savedFile string) error { fileInfo, err := os.Lstat(targetFile) if err == nil { if err = os.Chmod(newFile, fileInfo.Mode()); err != nil { - return errors.Wrap(err, "failed to set permission") + return fmt.Errorf("failed to set permission: %w", err) } } @@ -361,7 +361,7 @@ func downloadUpdate(ctx context.Context, beta bool, version, siteURL, newFile, p if packageFormat == "deb" || packageFormat == "rpm" { if err := ioutil.WriteFile(newFile, archiveBuf, 0644); err != nil { - return errors.Wrap(err, "cannot write temporary ."+packageFormat) + return fmt.Errorf("cannot write temporary .%s: %w", packageFormat, err) } return nil } diff --git a/cmd/selfupdate/verify.go b/cmd/selfupdate/verify.go index 9cc0cf9d5..74f87eab5 100644 --- a/cmd/selfupdate/verify.go +++ b/cmd/selfupdate/verify.go @@ -6,10 +6,10 @@ package selfupdate import ( "bytes" "context" + "errors" "fmt" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "golang.org/x/crypto/openpgp" "golang.org/x/crypto/openpgp/clearsign" diff --git a/cmd/serve/dlna/cds.go b/cmd/serve/dlna/cds.go index 87b676142..f3daf0cd8 100644 --- a/cmd/serve/dlna/cds.go +++ b/cmd/serve/dlna/cds.go @@ -3,6 +3,7 @@ package dlna import ( "context" "encoding/xml" + "errors" "fmt" "log" "net/http" @@ -15,7 +16,6 @@ import ( "github.com/anacrolix/dms/dlna" "github.com/anacrolix/dms/upnp" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/serve/dlna/upnpav" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/vfs" diff --git a/cmd/serve/dlna/data/data.go b/cmd/serve/dlna/data/data.go index 7e71f0083..8e142b99f 100644 --- a/cmd/serve/dlna/data/data.go +++ b/cmd/serve/dlna/data/data.go @@ -4,10 +4,10 @@ package data import ( + "fmt" "io/ioutil" "text/template" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -15,21 +15,21 @@ import ( func GetTemplate() (tpl *template.Template, err error) { templateFile, err := Assets.Open("rootDesc.xml.tmpl") if err != nil { - return nil, errors.Wrap(err, "get template open") + return nil, fmt.Errorf("get template open: %w", err) } defer fs.CheckClose(templateFile, &err) templateBytes, err := ioutil.ReadAll(templateFile) if err != nil { - return nil, errors.Wrap(err, "get template read") + return nil, fmt.Errorf("get template read: %w", err) } var templateString = string(templateBytes) tpl, err = template.New("rootDesc").Parse(templateString) if err != nil { - return nil, errors.Wrap(err, "get template parse") + return nil, fmt.Errorf("get template parse: %w", err) } return diff --git a/cmd/serve/docker/driver.go b/cmd/serve/docker/driver.go index eb8207f52..6b1db258c 100644 --- a/cmd/serve/docker/driver.go +++ b/cmd/serve/docker/driver.go @@ -3,6 +3,7 @@ package docker import ( "context" "encoding/json" + "fmt" "io/ioutil" "math/rand" "os" @@ -13,7 +14,6 @@ import ( "time" sysdnotify "github.com/iguanesolutions/go-systemd/v5/notify" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" @@ -44,12 +44,12 @@ func NewDriver(ctx context.Context, root string, mntOpt *mountlib.Options, vfsOp cacheDir := config.GetCacheDir() err := file.MkdirAll(cacheDir, 0700) if err != nil { - return nil, errors.Wrapf(err, "failed to create cache directory: %s", cacheDir) + return nil, fmt.Errorf("failed to create cache directory: %s: %w", cacheDir, err) } //err = file.MkdirAll(root, 0755) if err != nil { - return nil, errors.Wrapf(err, "failed to create mount root: %s", root) + return nil, fmt.Errorf("failed to create mount root: %s: %w", root, err) } // setup driver state @@ -72,7 +72,7 @@ func NewDriver(ctx context.Context, root string, mntOpt *mountlib.Options, vfsOp // restore from saved state if !forgetState { if err = drv.restoreState(ctx); err != nil { - return nil, errors.Wrap(err, "failed to restore state") + return nil, fmt.Errorf("failed to restore state: %w", err) } } @@ -89,7 +89,7 @@ func NewDriver(ctx context.Context, root string, mntOpt *mountlib.Options, vfsOp // notify systemd if err := sysdnotify.Ready(); err != nil { - return nil, errors.Wrap(err, "failed to notify systemd") + return nil, fmt.Errorf("failed to notify systemd: %w", err) } return drv, nil @@ -323,7 +323,7 @@ func (drv *Driver) saveState() error { data, err := json.Marshal(state) if err != nil { - return errors.Wrap(err, "failed to marshal state") + return fmt.Errorf("failed to marshal state: %w", err) } ctx := context.Background() @@ -335,7 +335,7 @@ func (drv *Driver) saveState() error { } time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) } - return errors.Wrap(err, "failed to save state") + return fmt.Errorf("failed to save state: %w", err) } // restoreState recreates volumes from saved driver state diff --git a/cmd/serve/docker/options.go b/cmd/serve/docker/options.go index 58c555d65..3b6fb07f1 100644 --- a/cmd/serve/docker/options.go +++ b/cmd/serve/docker/options.go @@ -1,6 +1,7 @@ package docker import ( + "fmt" "strconv" "strings" @@ -12,7 +13,6 @@ import ( "github.com/rclone/rclone/vfs/vfscommon" "github.com/rclone/rclone/vfs/vfsflags" - "github.com/pkg/errors" "github.com/spf13/pflag" ) @@ -62,7 +62,7 @@ func (vol *Volume) applyOptions(volOpt VolOpts) error { case "remote", "fs": p, err := fspath.Parse(str) if err != nil || p.Name == ":" { - return errors.Wrapf(err, "cannot parse path %q", str) + return fmt.Errorf("cannot parse path %q: %w", str, err) } fsName, fsPath, fsOpt = p.Name, p.Path, p.Config vol.Fs = str @@ -100,7 +100,7 @@ func (vol *Volume) applyOptions(volOpt VolOpts) error { } fsInfo, err := fs.Find(fsType) if err != nil { - return errors.Errorf("unknown filesystem type %q", fsType) + return fmt.Errorf("unknown filesystem type %q", fsType) } // handle remaining options, override fsOpt @@ -124,21 +124,21 @@ func (vol *Volume) applyOptions(volOpt VolOpts) error { ok = true } if err != nil { - return errors.Wrapf(err, "cannot parse option %q", key) + return fmt.Errorf("cannot parse option %q: %w", key, err) } if !ok { // try to use as a mount option in mntOpt ok, err = getMountOption(mntOpt, opt, key) if ok && err != nil { - return errors.Wrapf(err, "cannot parse mount option %q", key) + return fmt.Errorf("cannot parse mount option %q: %w", key, err) } } if !ok { // try as a vfs option in vfsOpt ok, err = getVFSOption(vfsOpt, opt, key) if ok && err != nil { - return errors.Wrapf(err, "cannot parse vfs option %q", key) + return fmt.Errorf("cannot parse vfs option %q: %w", key, err) } } @@ -149,11 +149,11 @@ func (vol *Volume) applyOptions(volOpt VolOpts) error { hasFsPrefix := optWithPrefix != fsOptName if !hasFsPrefix || fsInfo.Options.Get(fsOptName) == nil { fs.Logf(nil, "Option %q is not supported by backend %q", key, fsType) - return errors.Errorf("unsupported backend option %q", key) + return fmt.Errorf("unsupported backend option %q", key) } fsOpt[fsOptName], err = opt.GetString(key) if err != nil { - return errors.Wrapf(err, "cannot parse backend option %q", key) + return fmt.Errorf("cannot parse backend option %q: %w", key, err) } } } diff --git a/cmd/serve/docker/volume.go b/cmd/serve/docker/volume.go index 770a5f893..076736684 100644 --- a/cmd/serve/docker/volume.go +++ b/cmd/serve/docker/volume.go @@ -2,14 +2,14 @@ package docker import ( "context" + "errors" + "fmt" "os" "path/filepath" "runtime" "sort" "time" - "github.com/pkg/errors" - "github.com/rclone/rclone/cmd/mountlib" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" @@ -155,7 +155,7 @@ func (vol *Volume) checkMountpoint() error { _, err := os.Lstat(path) if os.IsNotExist(err) { if err = file.MkdirAll(path, 0700); err != nil { - return errors.Wrapf(err, "failed to create mountpoint: %s", path) + return fmt.Errorf("failed to create mountpoint: %s: %w", path, err) } } else if err != nil { return err @@ -182,7 +182,7 @@ func (vol *Volume) setup(ctx context.Context) error { _, mountFn := mountlib.ResolveMountMethod(vol.mountType) if mountFn == nil { if vol.mountType != "" { - return errors.Errorf("unsupported mount type %q", vol.mountType) + return fmt.Errorf("unsupported mount type %q", vol.mountType) } return errors.New("mount command unsupported by this build") } @@ -242,7 +242,7 @@ func (vol *Volume) clearCache() error { } root, err := VFS.Root() if err != nil { - return errors.Wrapf(err, "error reading root: %v", VFS.Fs()) + return fmt.Errorf("error reading root: %v: %w", VFS.Fs(), err) } root.ForgetAll() return nil diff --git a/cmd/serve/ftp/ftp.go b/cmd/serve/ftp/ftp.go index de7bc4ac6..a2a4df159 100644 --- a/cmd/serve/ftp/ftp.go +++ b/cmd/serve/ftp/ftp.go @@ -7,6 +7,7 @@ package ftp import ( "context" + "errors" "fmt" "io" "net" @@ -16,7 +17,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/serve/proxy" "github.com/rclone/rclone/cmd/serve/proxy/proxyflags" diff --git a/cmd/serve/http/data/data.go b/cmd/serve/http/data/data.go index 461e91663..06eb6a254 100644 --- a/cmd/serve/http/data/data.go +++ b/cmd/serve/http/data/data.go @@ -4,11 +4,11 @@ package data import ( + "fmt" "html/template" "io/ioutil" "time" - "github.com/pkg/errors" "github.com/spf13/pflag" "github.com/rclone/rclone/fs" @@ -61,14 +61,14 @@ func GetTemplate(tmpl string) (tpl *template.Template, err error) { if tmpl == "" { templateFile, err := Assets.Open("index.html") if err != nil { - return nil, errors.Wrap(err, "get template open") + return nil, fmt.Errorf("get template open: %w", err) } defer fs.CheckClose(templateFile, &err) templateBytes, err := ioutil.ReadAll(templateFile) if err != nil { - return nil, errors.Wrap(err, "get template read") + return nil, fmt.Errorf("get template read: %w", err) } templateString = string(templateBytes) @@ -76,7 +76,7 @@ func GetTemplate(tmpl string) (tpl *template.Template, err error) { } else { templateFile, err := ioutil.ReadFile(tmpl) if err != nil { - return nil, errors.Wrap(err, "get template open") + return nil, fmt.Errorf("get template open: %w", err) } templateString = string(templateFile) @@ -87,7 +87,7 @@ func GetTemplate(tmpl string) (tpl *template.Template, err error) { } tpl, err = template.New("index").Funcs(funcMap).Parse(templateString) if err != nil { - return nil, errors.Wrap(err, "get template parse") + return nil, fmt.Errorf("get template parse: %w", err) } return diff --git a/cmd/serve/httplib/httplib.go b/cmd/serve/httplib/httplib.go index 40fb62ffb..ae6583af9 100644 --- a/cmd/serve/httplib/httplib.go +++ b/cmd/serve/httplib/httplib.go @@ -18,7 +18,6 @@ import ( "time" auth "github.com/abbot/go-http-auth" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/serve/http/data" "github.com/rclone/rclone/fs" ) @@ -322,7 +321,7 @@ func NewServer(handler http.Handler, opt *Options) *Server { func (s *Server) Serve() error { ln, err := net.Listen("tcp", s.httpServer.Addr) if err != nil { - return errors.Wrapf(err, "start server failed") + return fmt.Errorf("start server failed: %w", err) } s.listener = ln s.waitChan = make(chan struct{}) diff --git a/cmd/serve/proxy/proxy.go b/cmd/serve/proxy/proxy.go index e55233fef..861861ee9 100644 --- a/cmd/serve/proxy/proxy.go +++ b/cmd/serve/proxy/proxy.go @@ -7,11 +7,12 @@ import ( "crypto/sha256" "crypto/subtle" "encoding/json" + "errors" + "fmt" "os/exec" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/config/configmap" @@ -144,7 +145,7 @@ func (p *Proxy) run(in map[string]string) (config configmap.Simple, err error) { cmd := exec.Command(p.cmdLine[0], p.cmdLine[1:]...) inBytes, err := json.MarshalIndent(in, "", "\t") if err != nil { - return nil, errors.Wrap(err, "Proxy.Call failed to marshal input: %v") + return nil, fmt.Errorf("proxy: failed to marshal input: %w", err) } var stdout, stderr bytes.Buffer cmd.Stdin = bytes.NewBuffer(inBytes) @@ -155,11 +156,11 @@ func (p *Proxy) run(in map[string]string) (config configmap.Simple, err error) { fs.Debugf(nil, "Calling proxy %v", p.cmdLine) duration := time.Since(start) if err != nil { - return nil, errors.Wrapf(err, "proxy: failed on %v: %q", p.cmdLine, strings.TrimSpace(string(stderr.Bytes()))) + return nil, fmt.Errorf("proxy: failed on %v: %q: %w", p.cmdLine, strings.TrimSpace(string(stderr.Bytes())), err) } err = json.Unmarshal(stdout.Bytes(), &config) if err != nil { - return nil, errors.Wrapf(err, "proxy: failed to read output: %q", string(stdout.Bytes())) + return nil, fmt.Errorf("proxy: failed to read output: %q: %w", string(stdout.Bytes()), err) } fs.Debugf(nil, "Proxy returned in %v", duration) @@ -171,7 +172,7 @@ func (p *Proxy) run(in map[string]string) (config configmap.Simple, err error) { if ok { obscuredValue, err := obscure.Obscure(value) if err != nil { - return nil, errors.Wrap(err, "proxy") + return nil, fmt.Errorf("proxy: %w", err) } config.Set(key, obscuredValue) } @@ -213,7 +214,7 @@ func (p *Proxy) call(user, auth string, isPublicKey bool) (value interface{}, er // Find the backend fsInfo, err := fs.Find(fsName) if err != nil { - return nil, errors.Wrapf(err, "proxy: couldn't find backend for %q", fsName) + return nil, fmt.Errorf("proxy: couldn't find backend for %q: %w", fsName, err) } // base name of config on user name. This may appear in logs @@ -247,7 +248,7 @@ func (p *Proxy) call(user, auth string, isPublicKey bool) (value interface{}, er return entry, true, nil }) if err != nil { - return nil, errors.Wrapf(err, "proxy: failed to create backend") + return nil, fmt.Errorf("proxy: failed to create backend: %w", err) } return value, nil } @@ -269,7 +270,7 @@ func (p *Proxy) Call(user, auth string, isPublicKey bool) (VFS *vfs.VFS, vfsKey // check we got what we were expecting entry, ok := value.(cacheEntry) if !ok { - return nil, "", errors.Errorf("proxy: value is not cache entry: %#v", value) + return nil, "", fmt.Errorf("proxy: value is not cache entry: %#v", value) } // Check the password / public key is correct in the cached entry. This diff --git a/cmd/serve/restic/restic.go b/cmd/serve/restic/restic.go index a90b3295a..53143957f 100644 --- a/cmd/serve/restic/restic.go +++ b/cmd/serve/restic/restic.go @@ -18,7 +18,6 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/config/flags" - "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fs/walk" "github.com/rclone/rclone/lib/http/serve" @@ -386,8 +385,7 @@ func (s *Server) listObjects(w http.ResponseWriter, r *http.Request, remote stri return nil }) if err != nil { - _, err = fserrors.Cause(err) - if err != fs.ErrorDirNotFound { + if !errors.Is(err, fs.ErrorDirNotFound) { fs.Errorf(remote, "list failed: %#v %T", err, err) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return diff --git a/cmd/serve/sftp/connection.go b/cmd/serve/sftp/connection.go index 15dc1049c..4575980f8 100644 --- a/cmd/serve/sftp/connection.go +++ b/cmd/serve/sftp/connection.go @@ -5,6 +5,7 @@ package sftp import ( "context" + "errors" "fmt" "io" "net" @@ -12,7 +13,6 @@ import ( "regexp" "strings" - "github.com/pkg/errors" "github.com/pkg/sftp" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" @@ -74,7 +74,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( } usage, err := about(ctx) if err != nil { - return errors.Wrap(err, "About failed") + return fmt.Errorf("About failed: %w", err) } total, used, free := int64(-1), int64(-1), int64(-1) if usage.Total != nil { @@ -94,7 +94,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( /dev/root %d %d %d %d%% / `, total, used, free, perc) if err != nil { - return errors.Wrap(err, "send output failed") + return fmt.Errorf("send output failed: %w", err) } case "md5sum", "sha1sum": ht := hash.MD5 @@ -113,7 +113,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( } else { node, err := c.vfs.Stat(args) if err != nil { - return errors.Wrapf(err, "hash failed finding file %q", args) + return fmt.Errorf("hash failed finding file %q: %w", args, err) } if node.IsDir() { return errors.New("can't hash directory") @@ -124,12 +124,12 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( } hashSum, err = o.Hash(ctx, ht) if err != nil { - return errors.Wrap(err, "hash failed") + return fmt.Errorf("hash failed: %w", err) } } _, err = fmt.Fprintf(out, "%s %s\n", hashSum, args) if err != nil { - return errors.Wrap(err, "send output failed") + return fmt.Errorf("send output failed: %w", err) } case "echo": // special cases for rclone command detection @@ -138,7 +138,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( if c.vfs.Fs().Hashes().Contains(hash.MD5) { _, err = fmt.Fprintf(out, "0bee89b07a248e27c83fc3d5951213c1 -\n") if err != nil { - return errors.Wrap(err, "send output failed") + return fmt.Errorf("send output failed: %w", err) } } else { return errors.New("md5 hash not supported") @@ -147,7 +147,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( if c.vfs.Fs().Hashes().Contains(hash.SHA1) { _, err = fmt.Fprintf(out, "03cfd743661f07975fa2f1220c5194cbaff48451 -\n") if err != nil { - return errors.Wrap(err, "send output failed") + return fmt.Errorf("send output failed: %w", err) } } else { return errors.New("sha1 hash not supported") @@ -155,11 +155,11 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( default: _, err = fmt.Fprintf(out, "%s\n", args) if err != nil { - return errors.Wrap(err, "send output failed") + return fmt.Errorf("send output failed: %w", err) } } default: - return errors.Errorf("%q not implemented\n", command) + return fmt.Errorf("%q not implemented", command) } return nil } @@ -268,7 +268,7 @@ func serveChannel(rwc io.ReadWriteCloser, h sftp.Handlers, what string) error { }() err := server.Serve() if err != nil && err != io.EOF { - return errors.Wrap(err, "completed with error") + return fmt.Errorf("completed with error: %w", err) } fs.Debugf(what, "exited session") return nil diff --git a/cmd/serve/sftp/server.go b/cmd/serve/sftp/server.go index 79446607d..d1fa92bf8 100644 --- a/cmd/serve/sftp/server.go +++ b/cmd/serve/sftp/server.go @@ -15,6 +15,7 @@ import ( "crypto/x509" "encoding/base64" "encoding/pem" + "errors" "fmt" "io/ioutil" "net" @@ -22,7 +23,6 @@ import ( "path/filepath" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/serve/proxy" "github.com/rclone/rclone/cmd/serve/proxy/proxyflags" "github.com/rclone/rclone/fs" @@ -237,7 +237,7 @@ func (s *server) serve() (err error) { // If loading a cached key failed, make the keys and retry err = file.MkdirAll(cachePath, 0700) if err != nil { - return errors.Wrap(err, "failed to create cache path") + return fmt.Errorf("failed to create cache path: %w", err) } if strings.HasSuffix(keyPath, string(os.PathSeparator)+"id_rsa") { const bits = 2048 @@ -250,10 +250,10 @@ func (s *server) serve() (err error) { fs.Logf(nil, "Generating Ed25519 key pair at %q", keyPath) err = makeEd25519SSHKeyPair(keyPath+".pub", keyPath) } else { - return errors.Errorf("don't know how to generate key pair %q", keyPath) + return fmt.Errorf("don't know how to generate key pair %q", keyPath) } if err != nil { - return errors.Wrap(err, "failed to create SSH key pair") + return fmt.Errorf("failed to create SSH key pair: %w", err) } // reload the new key private, err = loadPrivateKey(keyPath) @@ -270,7 +270,7 @@ func (s *server) serve() (err error) { // accepted. s.listener, err = net.Listen("tcp", s.opt.ListenAddr) if err != nil { - return errors.Wrap(err, "failed to listen for connection") + return fmt.Errorf("failed to listen for connection: %w", err) } fs.Logf(nil, "SFTP server listening on %v\n", s.listener.Addr()) @@ -313,11 +313,11 @@ func (s *server) Close() { func loadPrivateKey(keyPath string) (ssh.Signer, error) { privateBytes, err := ioutil.ReadFile(keyPath) if err != nil { - return nil, errors.Wrap(err, "failed to load private key") + return nil, fmt.Errorf("failed to load private key: %w", err) } private, err := ssh.ParsePrivateKey(privateBytes) if err != nil { - return nil, errors.Wrap(err, "failed to parse private key") + return nil, fmt.Errorf("failed to parse private key: %w", err) } return private, nil } @@ -328,13 +328,13 @@ func loadPrivateKey(keyPath string) (ssh.Signer, error) { func loadAuthorizedKeys(authorizedKeysPath string) (authorizedKeysMap map[string]struct{}, err error) { authorizedKeysBytes, err := ioutil.ReadFile(authorizedKeysPath) if err != nil { - return nil, errors.Wrap(err, "failed to load authorized keys") + return nil, fmt.Errorf("failed to load authorized keys: %w", err) } authorizedKeysMap = make(map[string]struct{}) for len(authorizedKeysBytes) > 0 { pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes) if err != nil { - return nil, errors.Wrap(err, "failed to parse authorized keys") + return nil, fmt.Errorf("failed to parse authorized keys: %w", err) } authorizedKeysMap[string(pubKey.Marshal())] = struct{}{} authorizedKeysBytes = bytes.TrimSpace(rest) diff --git a/cmd/serve/webdav/webdav.go b/cmd/serve/webdav/webdav.go index 531842936..a618c6c06 100644 --- a/cmd/serve/webdav/webdav.go +++ b/cmd/serve/webdav/webdav.go @@ -3,6 +3,8 @@ package webdav import ( "context" + "errors" + "fmt" "net/http" "os" "strings" @@ -16,7 +18,6 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" "github.com/rclone/rclone/fs/hash" - "github.com/rclone/rclone/lib/errors" "github.com/rclone/rclone/lib/http/serve" "github.com/rclone/rclone/vfs" "github.com/rclone/rclone/vfs/vfsflags" @@ -157,7 +158,7 @@ func (w *WebDAV) getVFS(ctx context.Context) (VFS *vfs.VFS, err error) { } VFS, ok := value.(*vfs.VFS) if !ok { - return nil, errors.Errorf("context value is not VFS: %#v", value) + return nil, fmt.Errorf("context value is not VFS: %#v", value) } return VFS, nil } diff --git a/cmd/settier/settier.go b/cmd/settier/settier.go index da8e54d59..97953727a 100644 --- a/cmd/settier/settier.go +++ b/cmd/settier/settier.go @@ -2,8 +2,8 @@ package settier import ( "context" + "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs/operations" "github.com/spf13/cobra" @@ -47,7 +47,7 @@ Or just provide remote directory and all files in directory will be tiered cmd.Run(false, false, command, func() error { isSupported := fsrc.Features().SetTier if !isSupported { - return errors.Errorf("Remote %s does not support settier", fsrc.Name()) + return fmt.Errorf("Remote %s does not support settier", fsrc.Name()) } return operations.SetTier(context.Background(), fsrc, tier) diff --git a/cmd/test/info/info.go b/cmd/test/info/info.go index 6b6b35f07..06cdd74e9 100644 --- a/cmd/test/info/info.go +++ b/cmd/test/info/info.go @@ -19,7 +19,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/cmd/test" "github.com/rclone/rclone/cmd/test/info/internal" @@ -441,7 +440,7 @@ func (r *results) checkStreaming() { func readInfo(ctx context.Context, f fs.Fs) error { err := f.Mkdir(ctx, "") if err != nil { - return errors.Wrap(err, "couldn't mkdir") + return fmt.Errorf("couldn't mkdir: %w", err) } r := newResults(ctx, f) if checkControl { diff --git a/cmd/touch/touch.go b/cmd/touch/touch.go index e778fbc7f..34ea22321 100644 --- a/cmd/touch/touch.go +++ b/cmd/touch/touch.go @@ -3,9 +3,10 @@ package touch import ( "bytes" "context" + "errors" + "fmt" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" @@ -89,7 +90,7 @@ func timeOfTouch() (time.Time, error) { if timeAsArgument != "" { var err error if t, err = parseTimeArgument(timeAsArgument); err != nil { - return t, errors.Wrap(err, "failed to parse timestamp argument") + return t, fmt.Errorf("failed to parse timestamp argument: %w", err) } } else { t = time.Now() @@ -114,7 +115,7 @@ func Touch(ctx context.Context, f fs.Fs, fileName string) error { fs.Debugf(nil, "Touch time %v", t) file, err := f.NewObject(ctx, fileName) if err != nil { - if errors.Cause(err) == fs.ErrorObjectNotFound { + if errors.Is(err, fs.ErrorObjectNotFound) { // Touch single non-existent file if notCreateNewFile { fs.Logf(f, "Not touching non-existent file due to --no-create") @@ -129,10 +130,10 @@ func Touch(ctx context.Context, f fs.Fs, fileName string) error { } fs.Debugf(f, "Touching (creating)") if err = createEmptyObject(ctx, fileName, t, f); err != nil { - return errors.Wrap(err, "failed to touch (create)") + return fmt.Errorf("failed to touch (create): %w", err) } } - if errors.Cause(err) == fs.ErrorIsDir { + if errors.Is(err, fs.ErrorIsDir) { if recursive { // Touch existing directory, recursive fs.Debugf(nil, "Touching files in directory recursively") @@ -149,7 +150,7 @@ func Touch(ctx context.Context, f fs.Fs, fileName string) error { fs.Debugf(f, "Touching %q", fileName) err = file.SetModTime(ctx, t) if err != nil { - return errors.Wrap(err, "failed to touch") + return fmt.Errorf("failed to touch: %w", err) } } return nil diff --git a/cmd/tree/tree.go b/cmd/tree/tree.go index 59eaef48e..52fa1d84c 100644 --- a/cmd/tree/tree.go +++ b/cmd/tree/tree.go @@ -11,7 +11,6 @@ import ( "time" "github.com/a8m/tree" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" @@ -100,7 +99,7 @@ short options as they conflict with rclone's short options. var err error outFile, err = os.Create(outFileName) if err != nil { - return errors.Errorf("failed to create output file: %v", err) + return fmt.Errorf("failed to create output file: %v", err) } } opts.VerSort = opts.VerSort || sort == "version" @@ -207,7 +206,7 @@ func (dirs Fs) Stat(filePath string) (fi os.FileInfo, err error) { } _, entry := dirtree.DirTree(dirs).Find(filePath) if entry == nil { - return nil, errors.Errorf("Couldn't find %q in directory cache", filePath) + return nil, fmt.Errorf("Couldn't find %q in directory cache", filePath) } return &FileInfo{entry}, nil } @@ -219,7 +218,7 @@ func (dirs Fs) ReadDir(dir string) (names []string, err error) { dir = strings.TrimLeft(dir, "/") entries, ok := dirs[dir] if !ok { - return nil, errors.Errorf("Couldn't find directory %q", dir) + return nil, fmt.Errorf("Couldn't find directory %q", dir) } for _, entry := range entries { names = append(names, path.Base(entry.Remote())) diff --git a/cmd/version/version.go b/cmd/version/version.go index 4ccca007a..3ec69e135 100644 --- a/cmd/version/version.go +++ b/cmd/version/version.go @@ -1,6 +1,7 @@ package version import ( + "errors" "fmt" "io/ioutil" "net/http" @@ -8,7 +9,6 @@ import ( "time" "github.com/coreos/go-semver/semver" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/flags" diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index ef079e36c..e3ed4972c 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -3,6 +3,7 @@ package accounting import ( "context" + "errors" "fmt" "io" "sync" @@ -11,7 +12,6 @@ import ( "github.com/rclone/rclone/fs/rc" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/asyncreader" "github.com/rclone/rclone/fs/fserrors" diff --git a/fs/accounting/stats_test.go b/fs/accounting/stats_test.go index 3359e3a7b..c22f0031b 100644 --- a/fs/accounting/stats_test.go +++ b/fs/accounting/stats_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" "github.com/stretchr/testify/assert" @@ -104,7 +103,7 @@ func TestStatsError(t *testing.T) { assert.Equal(t, t0, s.RetryAfter()) assert.Equal(t, e, s.GetLastError()) - err := errors.Wrap(fserrors.ErrorRetryAfter(t1), "potato") + err := fmt.Errorf("potato: %w", fserrors.ErrorRetryAfter(t1)) err = s.Error(err) assert.Equal(t, int64(3), s.GetErrors()) assert.False(t, s.HadFatalError()) diff --git a/fs/accounting/token_bucket.go b/fs/accounting/token_bucket.go index 5d7c87fba..c875c568f 100644 --- a/fs/accounting/token_bucket.go +++ b/fs/accounting/token_bucket.go @@ -2,10 +2,11 @@ package accounting import ( "context" + "errors" + "fmt" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" "golang.org/x/time/rate" @@ -201,7 +202,7 @@ func (tb *tokenBucket) rcBwlimit(ctx context.Context, in rc.Params) (out rc.Para var bws fs.BwTimetable err = bws.Set(bwlimit) if err != nil { - return out, errors.Wrap(err, "bad bwlimit") + return out, fmt.Errorf("bad bwlimit: %w", err) } if len(bws) != 1 { return out, errors.New("need exactly 1 bandwidth setting") diff --git a/fs/asyncreader/asyncreader.go b/fs/asyncreader/asyncreader.go index 92d389002..44f8fb245 100644 --- a/fs/asyncreader/asyncreader.go +++ b/fs/asyncreader/asyncreader.go @@ -4,11 +4,11 @@ package asyncreader import ( "context" + "errors" "io" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/pool" "github.com/rclone/rclone/lib/readers" diff --git a/fs/backend_config.go b/fs/backend_config.go index 97db87202..8d24f523d 100644 --- a/fs/backend_config.go +++ b/fs/backend_config.go @@ -6,11 +6,11 @@ package fs import ( "context" + "errors" "fmt" "strconv" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/config/configmap" ) @@ -188,7 +188,7 @@ func ConfigConfirm(state string, Default bool, name string, help string) (*Confi // If there is only one item it will short cut to the next state func ConfigChooseFixed(state string, name string, help string, items []OptionExample) (*ConfigOut, error) { if len(items) == 0 { - return nil, errors.Errorf("no items found in: %s", help) + return nil, fmt.Errorf("no items found in: %s", help) } choose := &ConfigOut{ State: state, @@ -323,7 +323,7 @@ func configAll(ctx context.Context, name string, m configmap.Mapper, ri *RegInfo if stateNumber != "" { optionNumber, err = strconv.Atoi(stateNumber) if err != nil { - return nil, errors.Wrap(err, "internal error: bad state number") + return nil, fmt.Errorf("internal error: bad state number: %w", err) } } @@ -393,7 +393,7 @@ func configAll(ctx context.Context, name string, m configmap.Mapper, ri *RegInfo } return ConfigGoto("*postconfig") } - return nil, errors.Errorf("internal error: bad state %q", state) + return nil, fmt.Errorf("internal error: bad state %q", state) } func backendConfigStep(ctx context.Context, name string, m configmap.Mapper, ri *RegInfo, choices configmap.Getter, in ConfigIn) (out *ConfigOut, err error) { @@ -415,7 +415,7 @@ func backendConfigStep(ctx context.Context, name string, m configmap.Mapper, ri in.State = "" return backendConfigStep(ctx, name, m, ri, choices, in) case strings.HasPrefix(in.State, "*"): - err = errors.Errorf("unknown internal state %q", in.State) + err = fmt.Errorf("unknown internal state %q", in.State) default: // Otherwise pass to backend if ri.Config == nil { diff --git a/fs/bwtimetable.go b/fs/bwtimetable.go index f0056e15d..5cf76ee26 100644 --- a/fs/bwtimetable.go +++ b/fs/bwtimetable.go @@ -2,12 +2,11 @@ package fs import ( "encoding/json" + "errors" "fmt" "strconv" "strings" "time" - - "github.com/pkg/errors" ) // BwPair represents an upload and a download bandwidth @@ -84,21 +83,21 @@ func (x BwTimetable) String() string { // Basic hour format checking func validateHour(HHMM string) error { if len(HHMM) != 5 { - return errors.Errorf("invalid time specification (hh:mm): %q", HHMM) + return fmt.Errorf("invalid time specification (hh:mm): %q", HHMM) } hh, err := strconv.Atoi(HHMM[0:2]) if err != nil { - return errors.Errorf("invalid hour in time specification %q: %v", HHMM, err) + return fmt.Errorf("invalid hour in time specification %q: %v", HHMM, err) } if hh < 0 || hh > 23 { - return errors.Errorf("invalid hour (must be between 00 and 23): %q", hh) + return fmt.Errorf("invalid hour (must be between 00 and 23): %q", hh) } mm, err := strconv.Atoi(HHMM[3:]) if err != nil { - return errors.Errorf("invalid minute in time specification: %q: %v", HHMM, err) + return fmt.Errorf("invalid minute in time specification: %q: %v", HHMM, err) } if mm < 0 || mm > 59 { - return errors.Errorf("invalid minute (must be between 00 and 59): %q", hh) + return fmt.Errorf("invalid minute (must be between 00 and 59): %q", hh) } return nil } @@ -127,7 +126,7 @@ func parseWeekday(dayOfWeek string) (int, error) { if dayOfWeek == "sat" || dayOfWeek == "saturday" { return 6, nil } - return 0, errors.Errorf("invalid weekday: %q", dayOfWeek) + return 0, fmt.Errorf("invalid weekday: %q", dayOfWeek) } // Set the bandwidth timetable. @@ -156,7 +155,7 @@ func (x *BwTimetable) Set(s string) error { // Format must be dayOfWeek-HH:MM,BW if len(tv) != 2 { - return errors.Errorf("invalid time/bandwidth specification: %q", tok) + return fmt.Errorf("invalid time/bandwidth specification: %q", tok) } weekday := 0 @@ -181,7 +180,7 @@ func (x *BwTimetable) Set(s string) error { } else { timespec := strings.Split(tv[0], "-") if len(timespec) != 2 { - return errors.Errorf("invalid time specification: %q", tv[0]) + return fmt.Errorf("invalid time specification: %q", tv[0]) } var err error weekday, err = parseWeekday(timespec[0]) diff --git a/fs/config.go b/fs/config.go index 0d43e04f9..480e0a39b 100644 --- a/fs/config.go +++ b/fs/config.go @@ -2,13 +2,12 @@ package fs import ( "context" + "errors" "net" "os" "strconv" "strings" "time" - - "github.com/pkg/errors" ) // Global diff --git a/fs/config/authorize.go b/fs/config/authorize.go index 452e8f8d4..fbfea2e0c 100644 --- a/fs/config/authorize.go +++ b/fs/config/authorize.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" ) @@ -22,7 +21,7 @@ func Authorize(ctx context.Context, args []string, noAutoBrowser bool) error { switch len(args) { case 1, 2, 3: default: - return errors.Errorf("invalid number of arguments: %d", len(args)) + return fmt.Errorf("invalid number of arguments: %d", len(args)) } Type := args[0] // FIXME could read this from input ri, err := fs.Find(Type) @@ -30,7 +29,7 @@ func Authorize(ctx context.Context, args []string, noAutoBrowser bool) error { return err } if ri.Config == nil { - return errors.Errorf("can't authorize fs %q", Type) + return fmt.Errorf("can't authorize fs %q", Type) } // Config map for remote diff --git a/fs/config/config.go b/fs/config/config.go index a2db8ddfd..a4f8a1644 100644 --- a/fs/config/config.go +++ b/fs/config/config.go @@ -4,6 +4,7 @@ package config import ( "context" "encoding/json" + "errors" "fmt" "log" mathrand "math/rand" @@ -15,7 +16,6 @@ import ( "time" "github.com/mitchellh/go-homedir" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" @@ -447,7 +447,7 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd ri, err := fs.Find(fsType) if err != nil { - return nil, errors.Errorf("couldn't find backend for type %q", fsType) + return nil, fmt.Errorf("couldn't find backend for type %q", fsType) } // Work out which options need to be obscured @@ -474,7 +474,7 @@ func updateRemote(ctx context.Context, name string, keyValues rc.Params, opt Upd // or we are forced to obscure vStr, err = obscure.Obscure(vStr) if err != nil { - return nil, errors.Wrap(err, "UpdateRemote: obscure failed") + return nil, fmt.Errorf("UpdateRemote: obscure failed: %w", err) } } } @@ -558,11 +558,11 @@ func PasswordRemote(ctx context.Context, name string, keyValues rc.Params) error func JSONListProviders() error { b, err := json.MarshalIndent(fs.Registry, "", " ") if err != nil { - return errors.Wrap(err, "failed to marshal examples") + return fmt.Errorf("failed to marshal examples: %w", err) } _, err = os.Stdout.Write(b) if err != nil { - return errors.Wrap(err, "failed to write providers list") + return fmt.Errorf("failed to write providers list: %w", err) } return nil } @@ -660,11 +660,11 @@ func Dump() error { dump := DumpRcBlob() b, err := json.MarshalIndent(dump, "", " ") if err != nil { - return errors.Wrap(err, "failed to marshal config dump") + return fmt.Errorf("failed to marshal config dump: %w", err) } _, err = os.Stdout.Write(b) if err != nil { - return errors.Wrap(err, "failed to write config dump") + return fmt.Errorf("failed to write config dump: %w", err) } return nil } diff --git a/fs/config/configfile/configfile.go b/fs/config/configfile/configfile.go index 6b93d4943..65971492d 100644 --- a/fs/config/configfile/configfile.go +++ b/fs/config/configfile/configfile.go @@ -3,6 +3,7 @@ package configfile import ( "bytes" + "fmt" "io/ioutil" "os" "path/filepath" @@ -10,7 +11,6 @@ import ( "sync" "github.com/Unknwon/goconfig" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/lib/file" @@ -106,17 +106,17 @@ func (s *Storage) Save() error { configPath := config.GetConfigPath() if configPath == "" { - return errors.Errorf("Failed to save config file: Path is empty") + return fmt.Errorf("Failed to save config file: Path is empty") } dir, name := filepath.Split(configPath) err := file.MkdirAll(dir, os.ModePerm) if err != nil { - return errors.Wrap(err, "failed to create config directory") + return fmt.Errorf("failed to create config directory: %w", err) } f, err := ioutil.TempFile(dir, name) if err != nil { - return errors.Errorf("Failed to create temp file for new config: %v", err) + return fmt.Errorf("Failed to create temp file for new config: %v", err) } defer func() { _ = f.Close() @@ -127,7 +127,7 @@ func (s *Storage) Save() error { var buf bytes.Buffer if err := goconfig.SaveConfigData(s.gc, &buf); err != nil { - return errors.Errorf("Failed to save config file: %v", err) + return fmt.Errorf("Failed to save config file: %v", err) } if err := config.Encrypt(&buf, f); err != nil { @@ -137,7 +137,7 @@ func (s *Storage) Save() error { _ = f.Sync() err = f.Close() if err != nil { - return errors.Errorf("Failed to close config file: %v", err) + return fmt.Errorf("Failed to close config file: %v", err) } var fileMode os.FileMode = 0600 @@ -157,10 +157,10 @@ func (s *Storage) Save() error { } if err = os.Rename(configPath, configPath+".old"); err != nil && !os.IsNotExist(err) { - return errors.Errorf("Failed to move previous config to backup location: %v", err) + return fmt.Errorf("Failed to move previous config to backup location: %v", err) } if err = os.Rename(f.Name(), configPath); err != nil { - return errors.Errorf("Failed to move newly written config from %s to final location: %v", f.Name(), err) + return fmt.Errorf("Failed to move newly written config from %s to final location: %v", f.Name(), err) } if err := os.Remove(configPath + ".old"); err != nil && !os.IsNotExist(err) { fs.Errorf(nil, "Failed to remove backup config file: %v", err) @@ -177,7 +177,7 @@ func (s *Storage) Serialize() (string, error) { s.check() var buf bytes.Buffer if err := goconfig.SaveConfigData(s.gc, &buf); err != nil { - return "", errors.Errorf("Failed to save config file: %v", err) + return "", fmt.Errorf("Failed to save config file: %v", err) } return buf.String(), nil diff --git a/fs/config/configmap/configmap.go b/fs/config/configmap/configmap.go index a37a2e654..516a91992 100644 --- a/fs/config/configmap/configmap.go +++ b/fs/config/configmap/configmap.go @@ -4,11 +4,10 @@ package configmap import ( "encoding/base64" "encoding/json" + "fmt" "sort" "strings" "unicode" - - "github.com/pkg/errors" ) // Priority of getters @@ -172,7 +171,7 @@ func (c Simple) Encode() (string, error) { } buf, err := json.Marshal(c) if err != nil { - return "", errors.Wrap(err, "encode simple map") + return "", fmt.Errorf("encode simple map: %w", err) } return base64.RawStdEncoding.EncodeToString(buf), nil } @@ -191,11 +190,11 @@ func (c Simple) Decode(in string) error { } decodedM, err := base64.RawStdEncoding.DecodeString(in) if err != nil { - return errors.Wrap(err, "decode simple map") + return fmt.Errorf("decode simple map: %w", err) } err = json.Unmarshal(decodedM, &c) if err != nil { - return errors.Wrap(err, "parse simple map") + return fmt.Errorf("parse simple map: %w", err) } return nil } diff --git a/fs/config/configstruct/configstruct.go b/fs/config/configstruct/configstruct.go index 181f25b5e..637e5e4ef 100644 --- a/fs/config/configstruct/configstruct.go +++ b/fs/config/configstruct/configstruct.go @@ -2,12 +2,12 @@ package configstruct import ( + "errors" "fmt" "reflect" "regexp" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/config/configmap" ) @@ -35,7 +35,7 @@ func StringToInterface(def interface{}, in string) (newValue interface{}, err er o := reflect.New(typ) n, err := fmt.Sscanln(in, o.Interface()) if err != nil { - return newValue, errors.Wrapf(err, "parsing %q as %T failed", in, def) + return newValue, fmt.Errorf("parsing %q as %T failed: %w", in, def, err) } if n != 1 { return newValue, errors.New("no items parsed") @@ -115,7 +115,7 @@ func Set(config configmap.Getter, opt interface{}) (err error) { // it isn't valid for all types. This makes // empty string be the equivalent of unset. if configValue != "" { - return errors.Wrapf(err, "couldn't parse config item %q = %q as %T", defaultItem.Name, configValue, defaultItem.Value) + return fmt.Errorf("couldn't parse config item %q = %q as %T: %w", defaultItem.Name, configValue, defaultItem.Value, err) } } else { newValue = newNewValue diff --git a/fs/config/crypt.go b/fs/config/crypt.go index b6f03fa2c..002e6c49f 100644 --- a/fs/config/crypt.go +++ b/fs/config/crypt.go @@ -7,6 +7,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/base64" + "errors" "fmt" "io" "io/ioutil" @@ -14,7 +15,6 @@ import ( "os/exec" "strings" - "github.com/pkg/errors" "golang.org/x/crypto/nacl/secretbox" "github.com/rclone/rclone/fs" @@ -95,12 +95,12 @@ func Decrypt(b io.ReadSeeker) (io.Reader, error) { if ers := strings.TrimSpace(stderr.String()); ers != "" { fs.Errorf(nil, "--password-command stderr: %s", ers) } - return nil, errors.Wrap(err, "password command failed") + return nil, fmt.Errorf("password command failed: %w", err) } if pass := strings.Trim(stdout.String(), "\r\n"); pass != "" { err := SetConfigPassword(pass) if err != nil { - return nil, errors.Wrap(err, "incorrect password") + return nil, fmt.Errorf("incorrect password: %w", err) } } else { return nil, errors.New("password-command returned empty string") @@ -130,7 +130,7 @@ func Decrypt(b io.ReadSeeker) (io.Reader, error) { dec := base64.NewDecoder(base64.StdEncoding, r) box, err := ioutil.ReadAll(dec) if err != nil { - return nil, errors.Wrap(err, "failed to load base64 encoded data") + return nil, fmt.Errorf("failed to load base64 encoded data: %w", err) } if len(box) < 24+secretbox.Overhead { return nil, errors.New("Configuration data too short") @@ -144,13 +144,13 @@ func Decrypt(b io.ReadSeeker) (io.Reader, error) { if err != nil { errRemove := os.Remove(envKeyFile) if errRemove != nil { - return nil, errors.Wrap(err, "unable to read obscured config key and unable to delete the temp file") + return nil, fmt.Errorf("unable to read obscured config key and unable to delete the temp file: %w", err) } - return nil, errors.Wrap(err, "unable to read obscured config key") + return nil, fmt.Errorf("unable to read obscured config key: %w", err) } errRemove := os.Remove(envKeyFile) if errRemove != nil { - return nil, errors.Wrap(errRemove, "unable to delete temp file with configKey") + return nil, fmt.Errorf("unable to delete temp file with configKey: %w", errRemove) } configKey = []byte(obscure.MustReveal(string(obscuredKey))) fs.Debugf(nil, "using _RCLONE_CONFIG_KEY_FILE for configKey") @@ -201,12 +201,12 @@ func Encrypt(src io.Reader, dst io.Writer) error { var nonce [24]byte n, _ := rand.Read(nonce[:]) if n != 24 { - return errors.Errorf("nonce short read: %d", n) + return fmt.Errorf("nonce short read: %d", n) } enc := base64.NewEncoder(base64.StdEncoding, dst) _, err := enc.Write(nonce[:]) if err != nil { - return errors.Errorf("Failed to write config file: %v", err) + return fmt.Errorf("Failed to write config file: %v", err) } var key [32]byte @@ -219,7 +219,7 @@ func Encrypt(src io.Reader, dst io.Writer) error { b := secretbox.Seal(nil, data, &nonce, &key) _, err = enc.Write(b) if err != nil { - return errors.Errorf("Failed to write config file: %v", err) + return fmt.Errorf("Failed to write config file: %v", err) } return enc.Close() } @@ -258,32 +258,32 @@ func SetConfigPassword(password string) error { if PassConfigKeyForDaemonization { tempFile, err := ioutil.TempFile("", "rclone") if err != nil { - return errors.Wrap(err, "cannot create temp file to store configKey") + return fmt.Errorf("cannot create temp file to store configKey: %w", err) } _, err = tempFile.WriteString(obscure.MustObscure(string(configKey))) if err != nil { errRemove := os.Remove(tempFile.Name()) if errRemove != nil { - return errors.Wrap(err, "error writing configKey to temp file and also error deleting it") + return fmt.Errorf("error writing configKey to temp file and also error deleting it: %w", err) } - return errors.Wrap(err, "error writing configKey to temp file") + return fmt.Errorf("error writing configKey to temp file: %w", err) } err = tempFile.Close() if err != nil { errRemove := os.Remove(tempFile.Name()) if errRemove != nil { - return errors.Wrap(err, "error closing temp file with configKey and also error deleting it") + return fmt.Errorf("error closing temp file with configKey and also error deleting it: %w", err) } - return errors.Wrap(err, "error closing temp file with configKey") + return fmt.Errorf("error closing temp file with configKey: %w", err) } fs.Debugf(nil, "saving configKey to temp file") err = os.Setenv("_RCLONE_CONFIG_KEY_FILE", tempFile.Name()) if err != nil { errRemove := os.Remove(tempFile.Name()) if errRemove != nil { - return errors.Wrap(err, "unable to set environment variable _RCLONE_CONFIG_KEY_FILE and unable to delete the temp file") + return fmt.Errorf("unable to set environment variable _RCLONE_CONFIG_KEY_FILE and unable to delete the temp file: %w", err) } - return errors.Wrap(err, "unable to set environment variable _RCLONE_CONFIG_KEY_FILE") + return fmt.Errorf("unable to set environment variable _RCLONE_CONFIG_KEY_FILE: %w", err) } } return nil diff --git a/fs/config/obscure/obscure.go b/fs/config/obscure/obscure.go index 2f2261f3d..17aae165b 100644 --- a/fs/config/obscure/obscure.go +++ b/fs/config/obscure/obscure.go @@ -6,10 +6,10 @@ import ( "crypto/cipher" "crypto/rand" "encoding/base64" + "errors" + "fmt" "io" "log" - - "github.com/pkg/errors" ) // crypt internals @@ -50,10 +50,10 @@ func Obscure(x string) (string, error) { ciphertext := make([]byte, aes.BlockSize+len(plaintext)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(cryptRand, iv); err != nil { - return "", errors.Wrap(err, "failed to read iv") + return "", fmt.Errorf("failed to read iv: %w", err) } if err := crypt(ciphertext[aes.BlockSize:], plaintext, iv); err != nil { - return "", errors.Wrap(err, "encrypt failed") + return "", fmt.Errorf("encrypt failed: %w", err) } return base64.RawURLEncoding.EncodeToString(ciphertext), nil } @@ -71,7 +71,7 @@ func MustObscure(x string) string { func Reveal(x string) (string, error) { ciphertext, err := base64.RawURLEncoding.DecodeString(x) if err != nil { - return "", errors.Wrap(err, "base64 decode failed when revealing password - is it obscured?") + return "", fmt.Errorf("base64 decode failed when revealing password - is it obscured?: %w", err) } if len(ciphertext) < aes.BlockSize { return "", errors.New("input too short when revealing password - is it obscured?") @@ -79,7 +79,7 @@ func Reveal(x string) (string, error) { buf := ciphertext[aes.BlockSize:] iv := ciphertext[:aes.BlockSize] if err := crypt(buf, buf, iv); err != nil { - return "", errors.Wrap(err, "decrypt failed when revealing password - is it obscured?") + return "", fmt.Errorf("decrypt failed when revealing password - is it obscured?: %w", err) } return string(buf), nil } diff --git a/fs/config/rc.go b/fs/config/rc.go index b5d4d0b91..fbbc7bdc9 100644 --- a/fs/config/rc.go +++ b/fs/config/rc.go @@ -2,8 +2,8 @@ package config import ( "context" + "errors" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" ) diff --git a/fs/config/ui.go b/fs/config/ui.go index 099ede7e5..5e2ded4af 100644 --- a/fs/config/ui.go +++ b/fs/config/ui.go @@ -5,6 +5,7 @@ package config import ( "bufio" "context" + "errors" "fmt" "log" "os" @@ -13,7 +14,6 @@ import ( "strings" "unicode/utf8" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" @@ -281,7 +281,7 @@ func backendConfig(ctx context.Context, name string, m configmap.Mapper, ri *fs. if value != "" { err := out.Option.Set(value) if err != nil { - return errors.Wrap(err, "failed to set option") + return fmt.Errorf("failed to set option: %w", err) } } in.Result = out.Option.String() diff --git a/fs/countsuffix.go b/fs/countsuffix.go index 93870a208..cea3b6329 100644 --- a/fs/countsuffix.go +++ b/fs/countsuffix.go @@ -2,13 +2,12 @@ package fs // CountSuffix is parsed by flag with k/M/G decimal suffixes import ( + "errors" "fmt" "math" "sort" "strconv" "strings" - - "github.com/pkg/errors" ) // CountSuffix is an int64 with a friendly way of printing setting @@ -138,7 +137,7 @@ func (x *CountSuffix) Set(s string) error { } default: if multiplierFound, multiplier = x.multiplierFromSymbol(suffix); !multiplierFound { - return errors.Errorf("bad suffix %q", suffix) + return fmt.Errorf("bad suffix %q", suffix) } } s = s[:len(s)-suffixLen] @@ -147,7 +146,7 @@ func (x *CountSuffix) Set(s string) error { return err } if value < 0 { - return errors.Errorf("size can't be negative %q", s) + return fmt.Errorf("size can't be negative %q", s) } value *= multiplier *x = CountSuffix(value) diff --git a/fs/cutoffmode.go b/fs/cutoffmode.go index 359143ee7..a58c5c452 100644 --- a/fs/cutoffmode.go +++ b/fs/cutoffmode.go @@ -3,8 +3,6 @@ package fs import ( "fmt" "strings" - - "github.com/pkg/errors" ) // CutoffMode describes the possible delete modes in the config @@ -40,7 +38,7 @@ func (m *CutoffMode) Set(s string) error { return nil } } - return errors.Errorf("Unknown cutoff mode %q", s) + return fmt.Errorf("Unknown cutoff mode %q", s) } // Type of the value @@ -52,7 +50,7 @@ func (m *CutoffMode) Type() string { func (m *CutoffMode) UnmarshalJSON(in []byte) error { return UnmarshalJSONFlag(in, m, func(i int64) error { if i < 0 || i >= int64(len(cutoffModeToString)) { - return errors.Errorf("Out of range cutoff mode %d", i) + return fmt.Errorf("Out of range cutoff mode %d", i) } *m = (CutoffMode)(i) return nil diff --git a/fs/dirtree/dirtree.go b/fs/dirtree/dirtree.go index 64f5b2512..cb78ab9df 100644 --- a/fs/dirtree/dirtree.go +++ b/fs/dirtree/dirtree.go @@ -10,7 +10,6 @@ import ( "time" "github.com/rclone/rclone/fs" - "github.com/rclone/rclone/lib/errors" ) // DirTree is a map of directories to entries @@ -153,7 +152,7 @@ func (dt DirTree) Prune(dirNames map[string]bool) error { case fs.Object: // do nothing default: - return errors.Errorf("unknown object type %T", entry) + return fmt.Errorf("unknown object type %T", entry) } } @@ -179,7 +178,7 @@ func (dt DirTree) Prune(dirNames map[string]bool) error { case fs.Object: // do nothing default: - return errors.Errorf("unknown object type %T", entry) + return fmt.Errorf("unknown object type %T", entry) } } diff --git a/fs/dump.go b/fs/dump.go index ec10b9259..f0c72bcab 100644 --- a/fs/dump.go +++ b/fs/dump.go @@ -3,8 +3,6 @@ package fs import ( "fmt" "strings" - - "github.com/pkg/errors" ) // DumpFlags describes the Dump options in force @@ -80,7 +78,7 @@ func (f *DumpFlags) Set(s string) error { } } if !found { - return errors.Errorf("Unknown dump flag %q", part) + return fmt.Errorf("Unknown dump flag %q", part) } } *f = flags diff --git a/fs/filter/filter.go b/fs/filter/filter.go index ef2a21c3a..72a25462f 100644 --- a/fs/filter/filter.go +++ b/fs/filter/filter.go @@ -4,6 +4,7 @@ package filter import ( "bufio" "context" + "errors" "fmt" "log" "os" @@ -12,7 +13,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "golang.org/x/sync/errgroup" ) @@ -318,7 +318,7 @@ func (f *Filter) AddRule(rule string) error { case strings.HasPrefix(rule, "+ "): return f.Add(true, rule[2:]) } - return errors.Errorf("malformed rule %q", rule) + return fmt.Errorf("malformed rule %q", rule) } // initAddFile creates f.files and f.dirs diff --git a/fs/filter/glob.go b/fs/filter/glob.go index f9198a886..fdaf96bdb 100644 --- a/fs/filter/glob.go +++ b/fs/filter/glob.go @@ -4,10 +4,9 @@ package filter import ( "bytes" + "fmt" "regexp" "strings" - - "github.com/pkg/errors" ) // GlobToRegexp converts an rsync style glob to a regexp @@ -33,7 +32,7 @@ func GlobToRegexp(glob string, ignoreCase bool) (*regexp.Regexp, error) { case 2: _, _ = re.WriteString(`.*`) default: - return errors.Errorf("too many stars in %q", glob) + return fmt.Errorf("too many stars in %q", glob) } } consecutiveStars = 0 @@ -76,16 +75,16 @@ func GlobToRegexp(glob string, ignoreCase bool) (*regexp.Regexp, error) { _, _ = re.WriteRune(c) inBrackets++ case ']': - return nil, errors.Errorf("mismatched ']' in glob %q", glob) + return nil, fmt.Errorf("mismatched ']' in glob %q", glob) case '{': if inBraces { - return nil, errors.Errorf("can't nest '{' '}' in glob %q", glob) + return nil, fmt.Errorf("can't nest '{' '}' in glob %q", glob) } inBraces = true _, _ = re.WriteRune('(') case '}': if !inBraces { - return nil, errors.Errorf("mismatched '{' and '}' in glob %q", glob) + return nil, fmt.Errorf("mismatched '{' and '}' in glob %q", glob) } _, _ = re.WriteRune(')') inBraces = false @@ -107,15 +106,15 @@ func GlobToRegexp(glob string, ignoreCase bool) (*regexp.Regexp, error) { return nil, err } if inBrackets > 0 { - return nil, errors.Errorf("mismatched '[' and ']' in glob %q", glob) + return nil, fmt.Errorf("mismatched '[' and ']' in glob %q", glob) } if inBraces { - return nil, errors.Errorf("mismatched '{' and '}' in glob %q", glob) + return nil, fmt.Errorf("mismatched '{' and '}' in glob %q", glob) } _, _ = re.WriteRune('$') result, err := regexp.Compile(re.String()) if err != nil { - return nil, errors.Wrapf(err, "bad glob pattern %q (regexp %q)", glob, re.String()) + return nil, fmt.Errorf("bad glob pattern %q (regexp %q): %w", glob, re.String(), err) } return result, nil } diff --git a/fs/fs.go b/fs/fs.go index fb4885d34..65d9c17d4 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -3,11 +3,10 @@ package fs import ( "context" + "errors" "io" "math" "time" - - "github.com/pkg/errors" ) // Constants diff --git a/fs/fs_test.go b/fs/fs_test.go index 4dad61f01..4e316b9b5 100644 --- a/fs/fs_test.go +++ b/fs/fs_test.go @@ -3,6 +3,7 @@ package fs import ( "context" "encoding/json" + "errors" "fmt" "os" "strings" @@ -13,7 +14,6 @@ import ( "github.com/spf13/pflag" "github.com/stretchr/testify/require" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/lib/pacer" diff --git a/fs/fserrors/enospc_error.go b/fs/fserrors/enospc_error.go index 930c5a174..410b513b1 100644 --- a/fs/fserrors/enospc_error.go +++ b/fs/fserrors/enospc_error.go @@ -6,13 +6,13 @@ package fserrors import ( "syscall" - "github.com/rclone/rclone/lib/errors" + liberrors "github.com/rclone/rclone/lib/errors" ) // IsErrNoSpace checks a possibly wrapped error to // see if it contains a ENOSPC error func IsErrNoSpace(cause error) (isNoSpc bool) { - errors.Walk(cause, func(c error) bool { + liberrors.Walk(cause, func(c error) bool { if c == syscall.ENOSPC { isNoSpc = true return true diff --git a/fs/fserrors/error.go b/fs/fserrors/error.go index b3fbfcce6..4cdf7ac9d 100644 --- a/fs/fserrors/error.go +++ b/fs/fserrors/error.go @@ -3,15 +3,21 @@ package fserrors import ( "context" + "errors" "fmt" "io" "net/http" "strings" "time" - "github.com/rclone/rclone/lib/errors" + liberrors "github.com/rclone/rclone/lib/errors" ) +// Must be satisfied for errors.Is/errors.As/Errors.Unwrap +type unwrapper interface { + Unwrap() error +} + // Retrier is an optional interface for error as to whether the // operation should be retried at a high level. // @@ -34,7 +40,7 @@ func (r retryError) Retry() bool { return true } -// Check interface +// Check interfaces var _ Retrier = retryError("") // RetryErrorf makes an error which indicates it would like to be retried @@ -53,8 +59,9 @@ func (err wrappedRetryError) Retry() bool { return true } -// Check interface +// Check interfaces var _ Retrier = wrappedRetryError{error(nil)} +var _ unwrapper = wrappedRetryError{} // RetryError makes an error which indicates it would like to be retried func RetryError(err error) error { @@ -64,14 +71,14 @@ func RetryError(err error) error { return wrappedRetryError{err} } -func (err wrappedRetryError) Cause() error { +func (err wrappedRetryError) Unwrap() error { return err.error } // IsRetryError returns true if err conforms to the Retry interface // and calling the Retry method returns true. func IsRetryError(err error) (isRetry bool) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(Retrier); ok { isRetry = r.Retry() return true @@ -101,8 +108,9 @@ func (err wrappedFatalError) Fatal() bool { return true } -// Check interface +// Check interfaces var _ Fataler = wrappedFatalError{error(nil)} +var _ unwrapper = wrappedFatalError{} // FatalError makes an error which indicates it is a fatal error and // the sync should stop. @@ -113,14 +121,14 @@ func FatalError(err error) error { return wrappedFatalError{err} } -func (err wrappedFatalError) Cause() error { +func (err wrappedFatalError) Unwrap() error { return err.error } // IsFatalError returns true if err conforms to the Fatal interface // and calling the Fatal method returns true. func IsFatalError(err error) (isFatal bool) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(Fataler); ok { isFatal = r.Fatal() return true @@ -153,8 +161,9 @@ func (err wrappedNoRetryError) NoRetry() bool { return true } -// Check interface +// Check interfaces var _ NoRetrier = wrappedNoRetryError{error(nil)} +var _ unwrapper = wrappedNoRetryError{} // NoRetryError makes an error which indicates the sync shouldn't be // retried. @@ -162,14 +171,14 @@ func NoRetryError(err error) error { return wrappedNoRetryError{err} } -func (err wrappedNoRetryError) Cause() error { +func (err wrappedNoRetryError) Unwrap() error { return err.error } // IsNoRetryError returns true if err conforms to the NoRetry // interface and calling the NoRetry method returns true. func IsNoRetryError(err error) (isNoRetry bool) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(NoRetrier); ok { isNoRetry = r.NoRetry() return true @@ -199,8 +208,9 @@ func (err wrappedNoLowLevelRetryError) NoLowLevelRetry() bool { return true } -// Check interface +// Check interfaces var _ NoLowLevelRetrier = wrappedNoLowLevelRetryError{error(nil)} +var _ unwrapper = wrappedNoLowLevelRetryError{} // NoLowLevelRetryError makes an error which indicates the sync // shouldn't be low level retried. @@ -208,15 +218,15 @@ func NoLowLevelRetryError(err error) error { return wrappedNoLowLevelRetryError{err} } -// Cause returns the underlying error -func (err wrappedNoLowLevelRetryError) Cause() error { +// Unwrap returns the underlying error +func (err wrappedNoLowLevelRetryError) Unwrap() error { return err.error } // IsNoLowLevelRetryError returns true if err conforms to the NoLowLevelRetry // interface and calling the NoLowLevelRetry method returns true. func IsNoLowLevelRetryError(err error) (isNoLowLevelRetry bool) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(NoLowLevelRetrier); ok { isNoLowLevelRetry = r.NoLowLevelRetry() return true @@ -257,13 +267,13 @@ func (e ErrorRetryAfter) RetryAfter() time.Time { return time.Time(e) } -// Check interface +// Check interfaces var _ RetryAfter = ErrorRetryAfter{} // RetryAfterErrorTime returns the time that the RetryAfter error // indicates or a Zero time.Time func RetryAfterErrorTime(err error) (retryAfter time.Time) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(RetryAfter); ok { retryAfter = r.RetryAfter() return true @@ -303,7 +313,7 @@ func (err *wrappedCountableError) IsCounted() bool { return err.isCounted } -func (err *wrappedCountableError) Cause() error { +func (err wrappedCountableError) Unwrap() error { return err.error } @@ -326,6 +336,7 @@ func Count(err error) { // Check interface var _ CountableError = &wrappedCountableError{error: error(nil)} +var _ unwrapper = wrappedCountableError{} // FsError makes an error which can keep a record that it is already counted // or not @@ -340,7 +351,7 @@ func FsError(err error) error { // library errors too. It returns true if any of the intermediate // errors had a Timeout() or Temporary() method which returned true. func Cause(cause error) (retriable bool, err error) { - errors.Walk(cause, func(c error) bool { + liberrors.Walk(cause, func(c error) bool { // Check for net error Timeout() if x, ok := c.(interface { Timeout() bool @@ -453,13 +464,3 @@ func ContextError(ctx context.Context, perr *error) bool { } return false } - -type causer interface { - Cause() error -} - -var ( - _ causer = wrappedRetryError{} - _ causer = wrappedFatalError{} - _ causer = wrappedNoRetryError{} -) diff --git a/fs/fserrors/error_test.go b/fs/fserrors/error_test.go index da8391b0e..a0cf4e2e6 100644 --- a/fs/fserrors/error_test.go +++ b/fs/fserrors/error_test.go @@ -2,6 +2,7 @@ package fserrors import ( "context" + "errors" "fmt" "io" "net" @@ -11,10 +12,33 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) +// withMessage wraps an error with a message +// +// This is for backwards compatibility with the now removed github.com/pkg/errors +type withMessage struct { + cause error + msg string +} + +func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } +func (w *withMessage) Cause() error { return w.cause } + +// wrap returns an error annotating err with a stack trace +// at the point Wrap is called, and the supplied message. +// If err is nil, Wrap returns nil. +func wrap(err error, message string) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: message, + } +} + var errUseOfClosedNetworkConnection = errors.New("use of closed network connection") // make a plausible network error with the underlying errno @@ -94,8 +118,8 @@ func TestCause(t *testing.T) { }{ {nil, false, nil}, {errPotato, false, errPotato}, - {errors.Wrap(errPotato, "potato"), false, errPotato}, - {errors.Wrap(errors.Wrap(errPotato, "potato2"), "potato"), false, errPotato}, + {fmt.Errorf("potato: %w", errPotato), false, errPotato}, + {fmt.Errorf("potato2: %w", wrap(errPotato, "potato")), false, errPotato}, {errUseOfClosedNetworkConnection, false, errUseOfClosedNetworkConnection}, {makeNetErr(syscall.EAGAIN), true, syscall.EAGAIN}, {makeNetErr(syscall.Errno(123123123)), false, syscall.Errno(123123123)}, @@ -124,7 +148,7 @@ func TestShouldRetry(t *testing.T) { }{ {nil, false}, {errors.New("potato"), false}, - {errors.Wrap(errUseOfClosedNetworkConnection, "connection"), true}, + {fmt.Errorf("connection: %w", errUseOfClosedNetworkConnection), true}, {io.EOF, true}, {io.ErrUnexpectedEOF, true}, {makeNetErr(syscall.EAGAIN), true}, @@ -133,7 +157,7 @@ func TestShouldRetry(t *testing.T) { {&url.Error{Op: "post", URL: "/", Err: errUseOfClosedNetworkConnection}, true}, {&url.Error{Op: "post", URL: "/", Err: fmt.Errorf("net/http: HTTP/1.x transport connection broken: %v", fmt.Errorf("http: ContentLength=%d with Body length %d", 100663336, 99590598))}, true}, { - errors.Wrap(&url.Error{ + wrap(&url.Error{ Op: "post", URL: "http://localhost/", Err: makeNetErr(syscall.EPIPE), @@ -141,7 +165,7 @@ func TestShouldRetry(t *testing.T) { true, }, { - errors.Wrap(&url.Error{ + wrap(&url.Error{ Op: "post", URL: "http://localhost/", Err: makeNetErr(syscall.Errno(123123123)), @@ -166,7 +190,7 @@ func TestRetryAfter(t *testing.T) { assert.Contains(t, e.Error(), "try again after") t0 := time.Now() - err := errors.Wrap(ErrorRetryAfter(t0), "potato") + err := fmt.Errorf("potato: %w", ErrorRetryAfter(t0)) assert.Equal(t, t0, RetryAfterErrorTime(err)) assert.True(t, IsRetryAfterError(err)) assert.Contains(t, e.Error(), "try again after") diff --git a/fs/hash/hash.go b/fs/hash/hash.go index 9d2f368de..a4eaf517d 100644 --- a/fs/hash/hash.go +++ b/fs/hash/hash.go @@ -5,6 +5,7 @@ import ( "crypto/sha1" "crypto/sha256" "encoding/hex" + "errors" "fmt" "hash" "hash/crc32" @@ -12,7 +13,6 @@ import ( "strings" "github.com/jzelinskie/whirlpool" - "github.com/pkg/errors" ) // Type indicates a standard hashing algorithm @@ -149,7 +149,7 @@ func (h *Type) Set(s string) error { *h = hash.hashType return nil } - return errors.Errorf("Unknown hash type %q", s) + return fmt.Errorf("Unknown hash type %q", s) } // Type of the value @@ -162,7 +162,7 @@ func (h Type) Type() string { // and this function must support all types. func fromTypes(set Set) (map[Type]hash.Hash, error) { if !set.SubsetOf(Supported()) { - return nil, errors.Errorf("requested set %08x contains unknown hash types", int(set)) + return nil, fmt.Errorf("requested set %08x contains unknown hash types", int(set)) } hashers := map[Type]hash.Hash{} diff --git a/fs/list/list.go b/fs/list/list.go index dfa8b688d..09d47ac8f 100644 --- a/fs/list/list.go +++ b/fs/list/list.go @@ -3,10 +3,10 @@ package list import ( "context" + "fmt" "sort" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/filter" ) @@ -67,7 +67,7 @@ func filterAndSortDir(ctx context.Context, entries fs.DirEntries, includeAll boo } } default: - return nil, errors.Errorf("unknown object type %T", entry) + return nil, fmt.Errorf("unknown object type %T", entry) } // check remote name belongs in this directory remote := entry.Remote() diff --git a/fs/log.go b/fs/log.go index a3bc71a4a..423352344 100644 --- a/fs/log.go +++ b/fs/log.go @@ -6,7 +6,6 @@ import ( "log" "os" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -62,7 +61,7 @@ func (l *LogLevel) Set(s string) error { return nil } } - return errors.Errorf("Unknown log level %q", s) + return fmt.Errorf("Unknown log level %q", s) } // Type of the value @@ -74,7 +73,7 @@ func (l *LogLevel) Type() string { func (l *LogLevel) UnmarshalJSON(in []byte) error { return UnmarshalJSONFlag(in, l, func(i int64) error { if i < 0 || i >= int64(LogLevel(len(logLevelToString))) { - return errors.Errorf("Unknown log level %d", i) + return fmt.Errorf("Unknown log level %d", i) } *l = (LogLevel)(i) return nil diff --git a/fs/march/march.go b/fs/march/march.go index d2193eb14..db045156d 100644 --- a/fs/march/march.go +++ b/fs/march/march.go @@ -3,13 +3,12 @@ package march import ( "context" + "fmt" "path" "sort" "strings" "sync" - "github.com/pkg/errors" - "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/dirtree" "github.com/rclone/rclone/fs/filter" @@ -216,7 +215,7 @@ func (m *March) Run(ctx context.Context) error { wg.Wait() if errCount > 1 { - return errors.Wrapf(jobError, "march failed with %d error(s): first error", errCount) + return fmt.Errorf("march failed with %d error(s): first error: %w", errCount, jobError) } return jobError } diff --git a/fs/mount_helper.go b/fs/mount_helper.go index 6a1a0953b..884b1f67c 100644 --- a/fs/mount_helper.go +++ b/fs/mount_helper.go @@ -1,14 +1,13 @@ package fs import ( + "errors" "fmt" "log" "os" "path/filepath" "runtime" "strings" - - "github.com/pkg/errors" ) func init() { @@ -83,7 +82,7 @@ func convertMountHelperArgs(origArgs []string) ([]string, error) { args = append(args, "--help") default: if strings.HasPrefix(arg, "-") { - return nil, errors.Errorf("flag %q is not supported in mount mode", arg) + return nil, fmt.Errorf("flag %q is not supported in mount mode", arg) } args = append(args, arg) } @@ -149,7 +148,7 @@ func convertMountHelperArgs(origArgs []string) ([]string, error) { } } if parseOpts { - return nil, errors.Errorf("dangling -o without argument") + return nil, fmt.Errorf("dangling -o without argument") } if vCount > 0 && !gotVerbose { diff --git a/fs/open_options.go b/fs/open_options.go index e39a23fb7..8d997118a 100644 --- a/fs/open_options.go +++ b/fs/open_options.go @@ -3,12 +3,12 @@ package fs import ( + "errors" "fmt" "net/http" "strconv" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/hash" ) diff --git a/fs/operations/check.go b/fs/operations/check.go index b7c36eec1..12c63e701 100644 --- a/fs/operations/check.go +++ b/fs/operations/check.go @@ -4,6 +4,8 @@ import ( "bufio" "bytes" "context" + "errors" + "fmt" "io" "os" "regexp" @@ -11,7 +13,6 @@ import ( "sync" "sync/atomic" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" @@ -79,7 +80,7 @@ func (c *checkMarch) DstOnly(dst fs.DirEntry) (recurse bool) { if c.opt.OneWay { return false } - err := errors.Errorf("File not in %v", c.opt.Fsrc) + err := fmt.Errorf("File not in %v", c.opt.Fsrc) fs.Errorf(dst, "%v", err) _ = fs.CountError(err) atomic.AddInt32(&c.differences, 1) @@ -101,7 +102,7 @@ func (c *checkMarch) DstOnly(dst fs.DirEntry) (recurse bool) { func (c *checkMarch) SrcOnly(src fs.DirEntry) (recurse bool) { switch src.(type) { case fs.Object: - err := errors.Errorf("File not in %v", c.opt.Fdst) + err := fmt.Errorf("File not in %v", c.opt.Fdst) fs.Errorf(src, "%v", err) _ = fs.CountError(err) atomic.AddInt32(&c.differences, 1) @@ -124,7 +125,7 @@ func (c *checkMarch) checkIdentical(ctx context.Context, dst, src fs.Object) (di tr.Done(ctx, err) }() if sizeDiffers(ctx, src, dst) { - err = errors.Errorf("Sizes differ") + err = fmt.Errorf("Sizes differ") fs.Errorf(src, "%v", err) return true, false, nil } @@ -173,7 +174,7 @@ func (c *checkMarch) Match(ctx context.Context, dst, src fs.DirEntry) (recurse b } }() } else { - err := errors.Errorf("is file on %v but directory on %v", c.opt.Fsrc, c.opt.Fdst) + err := fmt.Errorf("is file on %v but directory on %v", c.opt.Fsrc, c.opt.Fdst) fs.Errorf(src, "%v", err) _ = fs.CountError(err) atomic.AddInt32(&c.differences, 1) @@ -186,7 +187,7 @@ func (c *checkMarch) Match(ctx context.Context, dst, src fs.DirEntry) (recurse b if ok { return true } - err := errors.Errorf("is file on %v but directory on %v", c.opt.Fdst, c.opt.Fsrc) + err := fmt.Errorf("is file on %v but directory on %v", c.opt.Fdst, c.opt.Fsrc) fs.Errorf(dst, "%v", err) _ = fs.CountError(err) atomic.AddInt32(&c.differences, 1) @@ -258,7 +259,7 @@ func (c *checkMarch) reportResults(ctx context.Context, err error) error { } if c.differences > 0 { // Return an already counted error so we don't double count this error too - err = fserrors.FsError(errors.Errorf("%d differences found", c.differences)) + err = fserrors.FsError(fmt.Errorf("%d differences found", c.differences)) fserrors.Count(err) return err } @@ -277,7 +278,7 @@ func Check(ctx context.Context, opt *CheckOpt) error { return false, true, nil } if !same { - err = errors.Errorf("%v differ", ht) + err = fmt.Errorf("%v differ", ht) fs.Errorf(src, "%v", err) return true, false, nil } @@ -334,7 +335,7 @@ func CheckIdenticalDownload(ctx context.Context, dst, src fs.Object) (differ boo func checkIdenticalDownload(ctx context.Context, dst, src fs.Object) (differ bool, err error) { in1, err := dst.Open(ctx) if err != nil { - return true, errors.Wrapf(err, "failed to open %q", dst) + return true, fmt.Errorf("failed to open %q: %w", dst, err) } tr1 := accounting.Stats(ctx).NewTransfer(dst) defer func() { @@ -344,7 +345,7 @@ func checkIdenticalDownload(ctx context.Context, dst, src fs.Object) (differ boo in2, err := src.Open(ctx) if err != nil { - return true, errors.Wrapf(err, "failed to open %q", src) + return true, fmt.Errorf("failed to open %q: %w", src, err) } tr2 := accounting.Stats(ctx).NewTransfer(dst) defer func() { @@ -364,7 +365,7 @@ func CheckDownload(ctx context.Context, opt *CheckOpt) error { optCopy.Check = func(ctx context.Context, a, b fs.Object) (differ bool, noHash bool, err error) { differ, err = CheckIdenticalDownload(ctx, a, b) if err != nil { - return true, true, errors.Wrap(err, "failed to download") + return true, true, fmt.Errorf("failed to download: %w", err) } return differ, false, nil } @@ -386,19 +387,19 @@ func CheckSum(ctx context.Context, fsrc, fsum fs.Fs, sumFile string, hashType ha opt = &options // override supplied argument if !download && (hashType == hash.None || !opt.Fdst.Hashes().Contains(hashType)) { - return errors.Errorf("%s: hash type is not supported by file system: %s", hashType, opt.Fdst) + return fmt.Errorf("%s: hash type is not supported by file system: %s", hashType, opt.Fdst) } if sumFile == "" { - return errors.Errorf("not a sum file: %s", fsum) + return fmt.Errorf("not a sum file: %s", fsum) } sumObj, err := fsum.NewObject(ctx, sumFile) if err != nil { - return errors.Wrap(err, "cannot open sum file") + return fmt.Errorf("cannot open sum file: %w", err) } hashes, err := ParseSumFile(ctx, sumObj) if err != nil { - return errors.Wrap(err, "failed to parse sum file") + return fmt.Errorf("failed to parse sum file: %w", err) } ci := fs.GetConfig(ctx) @@ -421,7 +422,7 @@ func CheckSum(ctx context.Context, fsrc, fsum fs.Fs, sumFile string, hashType ha continue } // filesystem missed the file, sum wasn't consumed - err := errors.Errorf("File not in %v", opt.Fdst) + err := fmt.Errorf("File not in %v", opt.Fdst) fs.Errorf(filename, "%v", err) _ = fs.CountError(err) if lastErr == nil { diff --git a/fs/operations/check_test.go b/fs/operations/check_test.go index 4615bbd13..6f914abc0 100644 --- a/fs/operations/check_test.go +++ b/fs/operations/check_test.go @@ -3,6 +3,7 @@ package operations_test import ( "bytes" "context" + "errors" "fmt" "io" "log" @@ -11,7 +12,6 @@ import ( "strings" "testing" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/hash" diff --git a/fs/operations/dedupe.go b/fs/operations/dedupe.go index 11ad82dd8..1da760a7a 100644 --- a/fs/operations/dedupe.go +++ b/fs/operations/dedupe.go @@ -10,7 +10,6 @@ import ( "sort" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/hash" @@ -237,7 +236,7 @@ func (x *DeduplicateMode) Set(s string) error { case "list": *x = DeduplicateList default: - return errors.Errorf("Unknown mode for dedupe %q.", s) + return fmt.Errorf("unknown mode for dedupe %q", s) } return nil } @@ -319,7 +318,7 @@ func dedupeFindDuplicateDirs(ctx context.Context, f fs.Fs) (duplicateDirs [][]*d return nil }) if err != nil { - return nil, errors.Wrap(err, "find duplicate dirs") + return nil, fmt.Errorf("find duplicate dirs: %w", err) } // Make sure parents are before children @@ -341,11 +340,11 @@ func dedupeFindDuplicateDirs(ctx context.Context, f fs.Fs) (duplicateDirs [][]*d func dedupeMergeDuplicateDirs(ctx context.Context, f fs.Fs, duplicateDirs [][]*dedupeDir) error { mergeDirs := f.Features().MergeDirs if mergeDirs == nil { - return errors.Errorf("%v: can't merge directories", f) + return fmt.Errorf("%v: can't merge directories", f) } dirCacheFlush := f.Features().DirCacheFlush if dirCacheFlush == nil { - return errors.Errorf("%v: can't flush dir cache", f) + return fmt.Errorf("%v: can't flush dir cache", f) } for _, dedupeDirs := range duplicateDirs { if SkipDestructive(ctx, dedupeDirs[0].dir, "merge duplicate directories") { @@ -400,7 +399,7 @@ func Deduplicate(ctx context.Context, f fs.Fs, mode DeduplicateMode, byHash bool what := "names" if byHash { if ht == hash.None { - return errors.Errorf("%v has no hashes", f) + return fmt.Errorf("%v has no hashes", f) } what = ht.String() + " hashes" } diff --git a/fs/operations/lsjson.go b/fs/operations/lsjson.go index c4ab976c9..5af5a4295 100644 --- a/fs/operations/lsjson.go +++ b/fs/operations/lsjson.go @@ -2,11 +2,12 @@ package operations import ( "context" + "errors" + "fmt" "path" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/backend/crypt" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" @@ -118,14 +119,14 @@ func newListJSON(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOp if opt.ShowEncrypted { fsInfo, _, _, config, err := fs.ConfigFs(fsrc.Name() + ":" + fsrc.Root()) if err != nil { - return nil, errors.Wrap(err, "ListJSON failed to load config for crypt remote") + return nil, fmt.Errorf("ListJSON failed to load config for crypt remote: %w", err) } if fsInfo.Name != "crypt" { return nil, errors.New("The remote needs to be of type \"crypt\"") } lj.cipher, err = crypt.NewCipher(config) if err != nil { - return nil, errors.Wrap(err, "ListJSON failed to make new crypt remote") + return nil, fmt.Errorf("ListJSON failed to make new crypt remote: %w", err) } } features := fsrc.Features() @@ -237,19 +238,19 @@ func ListJSON(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOpt, for _, entry := range entries { item, err := lj.entry(ctx, entry) if err != nil { - return errors.Wrap(err, "creating entry failed in ListJSON") + return fmt.Errorf("creating entry failed in ListJSON: %w", err) } if item != nil { err = callback(item) if err != nil { - return errors.Wrap(err, "callback failed in ListJSON") + return fmt.Errorf("callback failed in ListJSON: %w", err) } } } return nil }) if err != nil { - return errors.Wrap(err, "error in ListJSON") + return fmt.Errorf("error in ListJSON: %w", err) } return nil } diff --git a/fs/operations/multithread.go b/fs/operations/multithread.go index db246b82a..b8ace21d5 100644 --- a/fs/operations/multithread.go +++ b/fs/operations/multithread.go @@ -2,9 +2,10 @@ package operations import ( "context" + "errors" + "fmt" "io" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "golang.org/x/sync/errgroup" @@ -76,7 +77,7 @@ func (mc *multiThreadCopyState) copyStream(ctx context.Context, stream int) (err rc, err := NewReOpen(ctx, mc.src, ci.LowLevelRetries, &fs.RangeOption{Start: start, End: end - 1}) if err != nil { - return errors.Wrap(err, "multipart copy: failed to open source") + return fmt.Errorf("multipart copy: failed to open source: %w", err) } defer fs.CheckClose(rc, &err) @@ -92,29 +93,29 @@ func (mc *multiThreadCopyState) copyStream(ctx context.Context, stream int) (err if nr > 0 { err = mc.acc.AccountRead(nr) if err != nil { - return errors.Wrap(err, "multipart copy: accounting failed") + return fmt.Errorf("multipart copy: accounting failed: %w", err) } nw, ew := mc.wc.WriteAt(buf[0:nr], offset) if nw > 0 { offset += int64(nw) } if ew != nil { - return errors.Wrap(ew, "multipart copy: write failed") + return fmt.Errorf("multipart copy: write failed: %w", ew) } if nr != nw { - return errors.Wrap(io.ErrShortWrite, "multipart copy") + return fmt.Errorf("multipart copy: %w", io.ErrShortWrite) } } if er != nil { if er != io.EOF { - return errors.Wrap(er, "multipart copy: read failed") + return fmt.Errorf("multipart copy: read failed: %w", er) } break } } if offset != end { - return errors.Errorf("multipart copy: wrote %d bytes but expected to write %d", offset-start, end-start) + return fmt.Errorf("multipart copy: wrote %d bytes but expected to write %d", offset-start, end-start) } fs.Debugf(mc.src, "multi-thread copy: stream %d/%d (%d-%d) size %v finished", stream+1, mc.streams, start, end, fs.SizeSuffix(end-start)) @@ -166,7 +167,7 @@ func multiThreadCopy(ctx context.Context, f fs.Fs, remote string, src fs.Object, // create write file handle mc.wc, err = openWriterAt(gCtx, remote, mc.size) if err != nil { - return nil, errors.Wrap(err, "multipart copy: failed to open destination") + return nil, fmt.Errorf("multipart copy: failed to open destination: %w", err) } fs.Debugf(src, "Starting multi-thread copy with %d parts of size %v", mc.streams, fs.SizeSuffix(mc.partSize)) @@ -182,19 +183,19 @@ func multiThreadCopy(ctx context.Context, f fs.Fs, remote string, src fs.Object, return nil, err } if closeErr != nil { - return nil, errors.Wrap(closeErr, "multi-thread copy: failed to close object after copy") + return nil, fmt.Errorf("multi-thread copy: failed to close object after copy: %w", closeErr) } obj, err := f.NewObject(ctx, remote) if err != nil { - return nil, errors.Wrap(err, "multi-thread copy: failed to find object after copy") + return nil, fmt.Errorf("multi-thread copy: failed to find object after copy: %w", err) } err = obj.SetModTime(ctx, src.ModTime(ctx)) switch err { case nil, fs.ErrorCantSetModTime, fs.ErrorCantSetModTimeWithoutDelete: default: - return nil, errors.Wrap(err, "multi-thread copy: failed to set modification time") + return nil, fmt.Errorf("multi-thread copy: failed to set modification time: %w", err) } fs.Debugf(src, "Finished multi-thread copy with %d parts of size %v", mc.streams, fs.SizeSuffix(mc.partSize)) diff --git a/fs/operations/operations.go b/fs/operations/operations.go index 30a0306e7..54311b5f7 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -7,6 +7,7 @@ import ( "encoding/base64" "encoding/csv" "encoding/hex" + "errors" "fmt" "io" "io/ioutil" @@ -21,7 +22,6 @@ import ( "sync/atomic" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/cache" @@ -441,7 +441,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj } in0, err = NewReOpen(ctx, src, ci.LowLevelRetries, options...) if err != nil { - err = errors.Wrap(err, "failed to open source object") + err = fmt.Errorf("failed to open source object: %w", err) } else { if src.Size() == -1 { // -1 indicates unknown size. Use Rcat to handle both remotes supporting and not supporting PutStream. @@ -512,7 +512,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj // Verify sizes are the same after transfer if sizeDiffers(ctx, src, dst) { - err = errors.Errorf("corrupted on transfer: sizes differ %d vs %d", src.Size(), dst.Size()) + err = fmt.Errorf("corrupted on transfer: sizes differ %d vs %d", src.Size(), dst.Size()) fs.Errorf(dst, "%v", err) err = fs.CountError(err) removeFailedCopy(ctx, dst) @@ -524,7 +524,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj // checkHashes has logged and counted errors equal, _, srcSum, dstSum, _ := checkHashes(ctx, src, dst, hashType) if !equal { - err = errors.Errorf("corrupted on transfer: %v hash differ %q vs %q", hashType, srcSum, dstSum) + err = fmt.Errorf("corrupted on transfer: %v hash differ %q vs %q", hashType, srcSum, dstSum) fs.Errorf(dst, "%v", err) err = fs.CountError(err) removeFailedCopy(ctx, dst) @@ -727,7 +727,7 @@ func DeleteFilesWithBackupDir(ctx context.Context, toBeDeleted fs.ObjectsChan, b fs.Debugf(nil, "Waiting for deletions to finish") wg.Wait() if errorCount > 0 { - err := errors.Errorf("failed to delete %d files", errorCount) + err := fmt.Errorf("failed to delete %d files", errorCount) if fatalErrorCount > 0 { return fserrors.FatalError(err) } @@ -968,7 +968,7 @@ func hashSum(ctx context.Context, ht hash.Type, downloadFlag bool, o fs.Object) } in, err := NewReOpen(ctx, o, fs.GetConfig(ctx).LowLevelRetries, options...) if err != nil { - return "ERROR", errors.Wrapf(err, "Failed to open file %v", o) + return "ERROR", fmt.Errorf("Failed to open file %v: %w", o, err) } // Account and buffer the transfer @@ -977,19 +977,19 @@ func hashSum(ctx context.Context, ht hash.Type, downloadFlag bool, o fs.Object) // Setup hasher hasher, err := hash.NewMultiHasherTypes(hash.NewHashSet(ht)) if err != nil { - return "UNSUPPORTED", errors.Wrap(err, "Hash unsupported") + return "UNSUPPORTED", fmt.Errorf("Hash unsupported: %w", err) } // Copy to hasher, downloading the file and passing directly to hash _, err = io.Copy(hasher, in) if err != nil { - return "ERROR", errors.Wrap(err, "Failed to copy file to hasher") + return "ERROR", fmt.Errorf("Failed to copy file to hasher: %w", err) } // Get hash and encode as hex byteSum, err := hasher.Sum(ht) if err != nil { - return "ERROR", errors.Wrap(err, "Hasher returned an error") + return "ERROR", fmt.Errorf("Hasher returned an error: %w", err) } sum = hex.EncodeToString(byteSum) } else { @@ -1000,10 +1000,10 @@ func hashSum(ctx context.Context, ht hash.Type, downloadFlag bool, o fs.Object) sum, err = o.Hash(ctx, ht) if err == hash.ErrUnsupported { - return "", errors.Wrap(err, "Hash unsupported") + return "", fmt.Errorf("Hash unsupported: %w", err) } if err != nil { - return "", errors.Wrapf(err, "Failed to get hash %v from backend: %v", ht, err) + return "", fmt.Errorf("Failed to get hash %v from backend: %v: %w", ht, err, err) } } @@ -1183,7 +1183,7 @@ func listToChan(ctx context.Context, f fs.Fs, dir string) fs.ObjectsChan { return nil }) if err != nil && err != fs.ErrorDirNotFound { - err = errors.Wrap(err, "failed to list") + err = fmt.Errorf("failed to list: %w", err) err = fs.CountError(err) fs.Errorf(nil, "%v", err) } @@ -1195,7 +1195,7 @@ func listToChan(ctx context.Context, f fs.Fs, dir string) fs.ObjectsChan { func CleanUp(ctx context.Context, f fs.Fs) error { doCleanUp := f.Features().CleanUp if doCleanUp == nil { - return errors.Errorf("%v doesn't support cleanup", f) + return fmt.Errorf("%v doesn't support cleanup", f) } if SkipDestructive(ctx, f, "clean up old files") { return nil @@ -1298,7 +1298,7 @@ func Rcat(ctx context.Context, fdst fs.Fs, dstFileName string, in io.ReadCloser, } src := object.NewStaticObjectInfo(dstFileName, modTime, int64(readCounter.BytesRead()), false, sums, fdst) if !Equal(ctx, src, dst) { - err = errors.Errorf("corrupted on transfer") + err = fmt.Errorf("corrupted on transfer") err = fs.CountError(err) fs.Errorf(dst, "%v", err) return err @@ -1326,7 +1326,7 @@ func Rcat(ctx context.Context, fdst fs.Fs, dstFileName string, in io.ReadCloser, fs.Debugf(fdst, "Target remote doesn't support streaming uploads, creating temporary local FS to spool file") tmpLocalFs, err := fs.TemporaryLocalFs(ctx) if err != nil { - return nil, errors.Wrap(err, "Failed to create temporary local FS to spool file") + return nil, fmt.Errorf("Failed to create temporary local FS to spool file: %w", err) } defer func() { err := Purge(ctx, tmpLocalFs, "") @@ -1361,7 +1361,7 @@ func Rcat(ctx context.Context, fdst fs.Fs, dstFileName string, in io.ReadCloser, func PublicLink(ctx context.Context, f fs.Fs, remote string, expire fs.Duration, unlink bool) (string, error) { doPublicLink := f.Features().PublicLink if doPublicLink == nil { - return "", errors.Errorf("%v doesn't support public links", f) + return "", fmt.Errorf("%v doesn't support public links", f) } return doPublicLink(ctx, remote, expire, unlink) } @@ -1410,7 +1410,7 @@ func Rmdirs(ctx context.Context, f fs.Fs, dir string, leaveRoot bool) error { return nil }) if err != nil { - return errors.Wrap(err, "failed to rmdirs") + return fmt.Errorf("failed to rmdirs: %w", err) } // Now delete the empty directories, starting from the longest path var toDelete []string @@ -1442,7 +1442,7 @@ func GetCompareDest(ctx context.Context) (CompareDest []fs.Fs, err error) { ci := fs.GetConfig(ctx) CompareDest, err = cache.GetArr(ctx, ci.CompareDest) if err != nil { - return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --compare-dest %q: %v", ci.CompareDest, err)) + return nil, fserrors.FatalError(fmt.Errorf("Failed to make fs for --compare-dest %q: %v", ci.CompareDest, err)) } return CompareDest, nil } @@ -1481,7 +1481,7 @@ func GetCopyDest(ctx context.Context, fdst fs.Fs) (CopyDest []fs.Fs, err error) ci := fs.GetConfig(ctx) CopyDest, err = cache.GetArr(ctx, ci.CopyDest) if err != nil { - return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --copy-dest %q: %v", ci.CopyDest, err)) + return nil, fserrors.FatalError(fmt.Errorf("Failed to make fs for --copy-dest %q: %v", ci.CopyDest, err)) } if !SameConfigArr(fdst, CopyDest) { return nil, fserrors.FatalError(errors.New("parameter to --copy-dest has to be on the same remote as destination")) @@ -1522,7 +1522,7 @@ func copyDest(ctx context.Context, fdst fs.Fs, dst, src fs.Object, CopyDest, bac if dst != nil && backupDir != nil { err = MoveBackupDir(ctx, backupDir, dst) if err != nil { - return false, errors.Wrap(err, "moving to --backup-dir failed") + return false, fmt.Errorf("moving to --backup-dir failed: %w", err) } // If successful zero out the dstObj as it is no longer there dst = nil @@ -1685,7 +1685,7 @@ func copyURLFn(ctx context.Context, dstFileName string, url string, dstFileNameF } defer fs.CheckClose(resp.Body, &err) if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return errors.Errorf("CopyURL failed: %s", resp.Status) + return fmt.Errorf("CopyURL failed: %s", resp.Status) } modTime, err := http.ParseTime(resp.Header.Get("Last-Modified")) if err != nil { @@ -1694,7 +1694,7 @@ func copyURLFn(ctx context.Context, dstFileName string, url string, dstFileNameF if dstFileNameFromURL { dstFileName = path.Base(resp.Request.URL.Path) if dstFileName == "." || dstFileName == "/" { - return errors.Errorf("CopyURL failed: file name wasn't found in url") + return fmt.Errorf("CopyURL failed: file name wasn't found in url") } fs.Debugf(dstFileName, "File name found in url") } @@ -1731,7 +1731,7 @@ func BackupDir(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, srcFileName string) if ci.BackupDir != "" { backupDir, err = cache.Get(ctx, ci.BackupDir) if err != nil { - return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --backup-dir %q: %v", ci.BackupDir, err)) + return nil, fserrors.FatalError(fmt.Errorf("Failed to make fs for --backup-dir %q: %v", ci.BackupDir, err)) } if !SameConfig(fdst, backupDir) { return nil, fserrors.FatalError(errors.New("parameter to --backup-dir has to be on the same remote as destination")) @@ -1818,7 +1818,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str if err == nil { return errors.New("found an already existing file with a randomly generated name. Try the operation again") } - return errors.Wrap(err, "error while attempting to move file to a temporary location") + return fmt.Errorf("error while attempting to move file to a temporary location: %w", err) } tr := accounting.Stats(ctx).NewTransfer(srcObj) defer func() { @@ -1826,7 +1826,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str }() tmpObj, err := Op(ctx, fdst, nil, tmpObjName, srcObj) if err != nil { - return errors.Wrap(err, "error while moving file to temporary location") + return fmt.Errorf("error while moving file to temporary location: %w", err) } _, err = Op(ctx, fdst, nil, dstFileName, tmpObj) return err @@ -1837,7 +1837,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str if ci.BackupDir != "" || ci.Suffix != "" { backupDir, err = BackupDir(ctx, fdst, fsrc, srcFileName) if err != nil { - return errors.Wrap(err, "creating Fs for --backup-dir failed") + return fmt.Errorf("creating Fs for --backup-dir failed: %w", err) } } if len(ci.CompareDest) > 0 { @@ -1860,7 +1860,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str if dstObj != nil && backupDir != nil { err = MoveBackupDir(ctx, backupDir, dstObj) if err != nil { - return errors.Wrap(err, "moving to --backup-dir failed") + return fmt.Errorf("moving to --backup-dir failed: %w", err) } // If successful zero out the dstObj as it is no longer there dstObj = nil @@ -1914,7 +1914,7 @@ func TouchDir(ctx context.Context, f fs.Fs, t time.Time, recursive bool) error { fs.Debugf(f, "Touching %q", o.Remote()) err := o.SetModTime(ctx, t) if err != nil { - err = errors.Wrap(err, "failed to touch") + err = fmt.Errorf("failed to touch: %w", err) err = fs.CountError(err) fs.Errorf(o, "%v", err) } @@ -2093,7 +2093,7 @@ func DirMove(ctx context.Context, f fs.Fs, srcRemote, dstRemote string) (err err // Load the directory tree into memory tree, err := walk.NewDirTree(ctx, f, srcRemote, true, -1) if err != nil { - return errors.Wrap(err, "RenameDir tree walk") + return fmt.Errorf("RenameDir tree walk: %w", err) } // Get the directories in sorted order @@ -2104,7 +2104,7 @@ func DirMove(ctx context.Context, f fs.Fs, srcRemote, dstRemote string) (err err dstPath := dstRemote + dir[len(srcRemote):] err := f.Mkdir(ctx, dstPath) if err != nil { - return errors.Wrap(err, "RenameDir mkdir") + return fmt.Errorf("RenameDir mkdir: %w", err) } } @@ -2144,14 +2144,14 @@ func DirMove(ctx context.Context, f fs.Fs, srcRemote, dstRemote string) (err err close(renames) err = g.Wait() if err != nil { - return errors.Wrap(err, "RenameDir renames") + return fmt.Errorf("RenameDir renames: %w", err) } // Remove the source directories in reverse order for i := len(dirs) - 1; i >= 0; i-- { err := f.Rmdir(ctx, dirs[i]) if err != nil { - return errors.Wrap(err, "RenameDir rmdir") + return fmt.Errorf("RenameDir rmdir: %w", err) } } diff --git a/fs/operations/operations_test.go b/fs/operations/operations_test.go index 719f2e8c5..c1f826df9 100644 --- a/fs/operations/operations_test.go +++ b/fs/operations/operations_test.go @@ -23,6 +23,7 @@ import ( "bytes" "context" "crypto/rand" + "errors" "fmt" "io" "io/ioutil" @@ -34,7 +35,6 @@ import ( "testing" "time" - "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/all" // import all backends "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -1593,8 +1593,8 @@ func TestTouchDir(t *testing.T) { err := operations.TouchDir(ctx, r.Fremote, timeValue, true) require.NoError(t, err) if accounting.Stats(ctx).GetErrors() != 0 { - err = errors.Cause(accounting.Stats(ctx).GetLastError()) - require.True(t, err == fs.ErrorCantSetModTime || err == fs.ErrorCantSetModTimeWithoutDelete) + err = accounting.Stats(ctx).GetLastError() + require.True(t, errors.Is(err, fs.ErrorCantSetModTime) || errors.Is(err, fs.ErrorCantSetModTimeWithoutDelete)) } else { file1.ModTime = timeValue file2.ModTime = timeValue diff --git a/fs/operations/rc.go b/fs/operations/rc.go index 9b5723c38..22aa4ac74 100644 --- a/fs/operations/rc.go +++ b/fs/operations/rc.go @@ -2,6 +2,7 @@ package operations import ( "context" + "fmt" "io" "mime" "mime/multipart" @@ -10,7 +11,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" ) @@ -140,15 +140,15 @@ func rcAbout(ctx context.Context, in rc.Params) (out rc.Params, err error) { } doAbout := f.Features().About if doAbout == nil { - return nil, errors.Errorf("%v doesn't support about", f) + return nil, fmt.Errorf("%v doesn't support about", f) } u, err := doAbout(ctx) if err != nil { - return nil, errors.Wrap(err, "about call failed") + return nil, fmt.Errorf("about call failed: %w", err) } err = rc.Reshape(&out, u) if err != nil { - return nil, errors.Wrap(err, "about Reshape failed") + return nil, fmt.Errorf("about Reshape failed: %w", err) } return out, nil } @@ -469,7 +469,7 @@ func rcFsInfo(ctx context.Context, in rc.Params) (out rc.Params, err error) { info := GetFsInfo(f) err = rc.Reshape(&out, info) if err != nil { - return nil, errors.Wrap(err, "fsinfo Reshape failed") + return nil, fmt.Errorf("fsinfo Reshape failed: %w", err) } return out, nil } @@ -533,7 +533,7 @@ func rcBackend(ctx context.Context, in rc.Params) (out rc.Params, err error) { } doCommand := f.Features().Command if doCommand == nil { - return nil, errors.Errorf("%v: doesn't support backend commands", f) + return nil, fmt.Errorf("%v: doesn't support backend commands", f) } command, err := in.GetString("command") if err != nil { @@ -551,7 +551,7 @@ func rcBackend(ctx context.Context, in rc.Params) (out rc.Params, err error) { } result, err := doCommand(context.Background(), command, arg, opt) if err != nil { - return nil, errors.Wrapf(err, "command %q failed", command) + return nil, fmt.Errorf("command %q failed: %w", command, err) } out = make(rc.Params) diff --git a/fs/operations/reopen.go b/fs/operations/reopen.go index 688c5d057..1f575d7cc 100644 --- a/fs/operations/reopen.go +++ b/fs/operations/reopen.go @@ -2,10 +2,10 @@ package operations import ( "context" + "errors" "io" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" ) diff --git a/fs/operations/reopen_test.go b/fs/operations/reopen_test.go index d7f7fbe94..3a75bc0bc 100644 --- a/fs/operations/reopen_test.go +++ b/fs/operations/reopen_test.go @@ -2,11 +2,11 @@ package operations import ( "context" + "errors" "io" "io/ioutil" "testing" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fstest/mockobject" diff --git a/fs/rc/config.go b/fs/rc/config.go index c996b3447..f0cc4503a 100644 --- a/fs/rc/config.go +++ b/fs/rc/config.go @@ -6,8 +6,8 @@ package rc import ( "context" + "fmt" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/filter" ) @@ -146,16 +146,16 @@ func rcOptionsSet(ctx context.Context, in Params) (out Params, err error) { for name, options := range in { current := optionBlock[name] if current == nil { - return nil, errors.Errorf("unknown option block %q", name) + return nil, fmt.Errorf("unknown option block %q", name) } err := Reshape(current, options) if err != nil { - return nil, errors.Wrapf(err, "failed to write options from block %q", name) + return nil, fmt.Errorf("failed to write options from block %q: %w", name, err) } if reload := optionReload[name]; reload != nil { err = reload(ctx) if err != nil { - return nil, errors.Wrapf(err, "failed to reload options from block %q", name) + return nil, fmt.Errorf("failed to reload options from block %q: %w", name, err) } } } diff --git a/fs/rc/config_test.go b/fs/rc/config_test.go index 144edc352..01b25983c 100644 --- a/fs/rc/config_test.go +++ b/fs/rc/config_test.go @@ -3,10 +3,10 @@ package rc import ( "context" "encoding/json" + "errors" "fmt" "testing" - "github.com/pkg/errors" "github.com/rclone/rclone/cmd/serve/httplib" "github.com/rclone/rclone/fs" "github.com/stretchr/testify/assert" diff --git a/fs/rc/internal.go b/fs/rc/internal.go index 50e2765d3..10077ae09 100644 --- a/fs/rc/internal.go +++ b/fs/rc/internal.go @@ -4,6 +4,7 @@ package rc import ( "context" + "fmt" "net/http" "os" "os/exec" @@ -12,7 +13,6 @@ import ( "time" "github.com/coreos/go-semver/semver" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/obscure" @@ -60,7 +60,7 @@ Useful for testing error handling.`, // Return an error regardless func rcError(ctx context.Context, in Params) (out Params, err error) { - return nil, errors.Errorf("arbitrary error on input %+v", in) + return nil, fmt.Errorf("arbitrary error on input %+v", in) } func init() { @@ -422,7 +422,7 @@ func rcRunCommand(ctx context.Context, in Params) (out Params, err error) { var httpResponse http.ResponseWriter httpResponse, err = in.GetHTTPResponseWriter() if err != nil { - return nil, errors.Errorf("response object is required\n" + err.Error()) + return nil, fmt.Errorf("response object is required\n" + err.Error()) } var allArgs = []string{} @@ -475,7 +475,7 @@ func rcRunCommand(ctx context.Context, in Params) (out Params, err error) { cmd.Stdout = httpResponse cmd.Stderr = httpResponse } else { - return nil, errors.Errorf("Unknown returnType %q", returnType) + return nil, fmt.Errorf("Unknown returnType %q", returnType) } err = cmd.Run() diff --git a/fs/rc/jobs/job.go b/fs/rc/jobs/job.go index 40a098400..e452fe241 100644 --- a/fs/rc/jobs/job.go +++ b/fs/rc/jobs/job.go @@ -4,13 +4,13 @@ package jobs import ( "context" + "errors" "fmt" "runtime/debug" "sync" "sync/atomic" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" @@ -88,7 +88,7 @@ func (job *Job) removeListener(fn *func()) { func (job *Job) run(ctx context.Context, fn rc.Func, in rc.Params) { defer func() { if r := recover(); r != nil { - job.finish(nil, errors.Errorf("panic received: %v \n%s", r, string(debug.Stack()))) + job.finish(nil, fmt.Errorf("panic received: %v \n%s", r, string(debug.Stack()))) } }() job.finish(fn(ctx, in)) @@ -352,7 +352,7 @@ func rcJobStatus(ctx context.Context, in rc.Params) (out rc.Params, err error) { out = make(rc.Params) err = rc.Reshape(&out, job) if err != nil { - return nil, errors.Wrap(err, "reshape failed in job status") + return nil, fmt.Errorf("reshape failed in job status: %w", err) } return out, nil } diff --git a/fs/rc/jobs/job_test.go b/fs/rc/jobs/job_test.go index 688ca04e8..3fcd4530b 100644 --- a/fs/rc/jobs/job_test.go +++ b/fs/rc/jobs/job_test.go @@ -2,11 +2,11 @@ package jobs import ( "context" + "errors" "runtime" "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" diff --git a/fs/rc/js/main.go b/fs/rc/js/main.go index b5eb93cb7..eb536573e 100644 --- a/fs/rc/js/main.go +++ b/fs/rc/js/main.go @@ -10,12 +10,13 @@ package main import ( "context" "encoding/json" + "errors" + "fmt" "log" "net/http" "runtime" "syscall/js" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" @@ -54,10 +55,9 @@ func paramToValue(in rc.Params) (out js.Value) { func errorValue(method string, in js.Value, err error) js.Value { fs.Errorf(nil, "rc: %q: error: %v", method, err) // Adjust the error return for some well known errors - errOrig := errors.Cause(err) status := http.StatusInternalServerError switch { - case errOrig == fs.ErrorDirNotFound || errOrig == fs.ErrorObjectNotFound: + case errors.Is(err, fs.ErrorDirNotFound) || errors.Is(err, fs.ErrorObjectNotFound): status = http.StatusNotFound case rc.IsErrParamInvalid(err) || rc.IsErrParamNotFound(err): status = http.StatusBadRequest @@ -89,7 +89,7 @@ func rcCallback(this js.Value, args []js.Value) interface{} { inJSON := jsJSON.Call("stringify", inRaw).String() err := json.Unmarshal([]byte(inJSON), &in) if err != nil { - return errorValue(method, inRaw, errors.Wrap(err, "couldn't unmarshal input")) + return errorValue(method, inRaw, fmt.Errorf("couldn't unmarshal input: %w", err)) } default: return errorValue(method, inRaw, errors.New("in parameter must be null or object")) @@ -97,12 +97,12 @@ func rcCallback(this js.Value, args []js.Value) interface{} { call := rc.Calls.Get(method) if call == nil { - return errorValue(method, inRaw, errors.Errorf("method %q not found", method)) + return errorValue(method, inRaw, fmt.Errorf("method %q not found", method)) } out, err := call.Fn(ctx, in) if err != nil { - return errorValue(method, inRaw, errors.Wrap(err, "method call failed")) + return errorValue(method, inRaw, fmt.Errorf("method call failed: %w", err)) } if out == nil { return nil @@ -110,7 +110,7 @@ func rcCallback(this js.Value, args []js.Value) interface{} { var out2 map[string]interface{} err = rc.Reshape(&out2, out) if err != nil { - return errorValue(method, inRaw, errors.Wrap(err, "result reshape failed")) + return errorValue(method, inRaw, fmt.Errorf("result reshape failed: %w", err)) } return js.ValueOf(out2) diff --git a/fs/rc/params.go b/fs/rc/params.go index 23b8a64d8..a2eabb6f4 100644 --- a/fs/rc/params.go +++ b/fs/rc/params.go @@ -4,14 +4,13 @@ package rc import ( "encoding/json" + "errors" "fmt" "math" "net/http" "strconv" "time" - "github.com/pkg/errors" - "github.com/rclone/rclone/fs" ) @@ -75,11 +74,11 @@ func IsErrParamInvalid(err error) bool { func Reshape(out interface{}, in interface{}) error { b, err := json.Marshal(in) if err != nil { - return errors.Wrapf(err, "Reshape failed to Marshal") + return fmt.Errorf("Reshape failed to Marshal: %w", err) } err = json.Unmarshal(b, out) if err != nil { - return errors.Wrapf(err, "Reshape failed to Unmarshal") + return fmt.Errorf("Reshape failed to Unmarshal: %w", err) } return nil } @@ -117,7 +116,7 @@ func (p Params) GetHTTPRequest() (*http.Request, error) { } request, ok := value.(*http.Request) if !ok { - return nil, ErrParamInvalid{errors.Errorf("expecting http.request value for key %q (was %T)", key, value)} + return nil, ErrParamInvalid{fmt.Errorf("expecting http.request value for key %q (was %T)", key, value)} } return request, nil } @@ -134,7 +133,7 @@ func (p Params) GetHTTPResponseWriter() (http.ResponseWriter, error) { } request, ok := value.(http.ResponseWriter) if !ok { - return nil, ErrParamInvalid{errors.Errorf("expecting http.ResponseWriter value for key %q (was %T)", key, value)} + return nil, ErrParamInvalid{fmt.Errorf("expecting http.ResponseWriter value for key %q (was %T)", key, value)} } return request, nil } @@ -150,7 +149,7 @@ func (p Params) GetString(key string) (string, error) { } str, ok := value.(string) if !ok { - return "", ErrParamInvalid{errors.Errorf("expecting string value for key %q (was %T)", key, value)} + return "", ErrParamInvalid{fmt.Errorf("expecting string value for key %q (was %T)", key, value)} } return str, nil } @@ -171,17 +170,17 @@ func (p Params) GetInt64(key string) (int64, error) { return x, nil case float64: if x > math.MaxInt64 || x < math.MinInt64 { - return 0, ErrParamInvalid{errors.Errorf("key %q (%v) overflows int64 ", key, value)} + return 0, ErrParamInvalid{fmt.Errorf("key %q (%v) overflows int64 ", key, value)} } return int64(x), nil case string: i, err := strconv.ParseInt(x, 10, 0) if err != nil { - return 0, ErrParamInvalid{errors.Wrapf(err, "couldn't parse key %q (%v) as int64", key, value)} + return 0, ErrParamInvalid{fmt.Errorf("couldn't parse key %q (%v) as int64: %w", key, value, err)} } return i, nil } - return 0, ErrParamInvalid{errors.Errorf("expecting int64 value for key %q (was %T)", key, value)} + return 0, ErrParamInvalid{fmt.Errorf("expecting int64 value for key %q (was %T)", key, value)} } // GetFloat64 gets a float64 parameter from the input @@ -203,11 +202,11 @@ func (p Params) GetFloat64(key string) (float64, error) { case string: f, err := strconv.ParseFloat(x, 64) if err != nil { - return 0, ErrParamInvalid{errors.Wrapf(err, "couldn't parse key %q (%v) as float64", key, value)} + return 0, ErrParamInvalid{fmt.Errorf("couldn't parse key %q (%v) as float64: %w", key, value, err)} } return f, nil } - return 0, ErrParamInvalid{errors.Errorf("expecting float64 value for key %q (was %T)", key, value)} + return 0, ErrParamInvalid{fmt.Errorf("expecting float64 value for key %q (was %T)", key, value)} } // GetBool gets a boolean parameter from the input @@ -231,11 +230,11 @@ func (p Params) GetBool(key string) (bool, error) { case string: b, err := strconv.ParseBool(x) if err != nil { - return false, ErrParamInvalid{errors.Wrapf(err, "couldn't parse key %q (%v) as bool", key, value)} + return false, ErrParamInvalid{fmt.Errorf("couldn't parse key %q (%v) as bool: %w", key, value, err)} } return b, nil } - return false, ErrParamInvalid{errors.Errorf("expecting bool value for key %q (was %T)", key, value)} + return false, ErrParamInvalid{fmt.Errorf("expecting bool value for key %q (was %T)", key, value)} } // GetStruct gets a struct from key from the input into the struct @@ -257,7 +256,7 @@ func (p Params) GetStruct(key string, out interface{}) error { return nil } } - return ErrParamInvalid{errors.Wrapf(err, "key %q", key)} + return ErrParamInvalid{fmt.Errorf("key %q: %w", key, err)} } return nil } @@ -280,7 +279,7 @@ func (p Params) GetDuration(key string) (time.Duration, error) { } duration, err := fs.ParseDuration(s) if err != nil { - return 0, ErrParamInvalid{errors.Wrap(err, "parse duration")} + return 0, ErrParamInvalid{fmt.Errorf("parse duration: %w", err)} } return duration, nil } @@ -292,9 +291,8 @@ func (p Params) GetDuration(key string) (time.Duration, error) { // It returns a Params and an updated status code func Error(path string, in Params, err error, status int) (Params, int) { // Adjust the status code for some well known errors - errOrig := errors.Cause(err) switch { - case errOrig == fs.ErrorDirNotFound || errOrig == fs.ErrorObjectNotFound: + case errors.Is(err, fs.ErrorDirNotFound) || errors.Is(err, fs.ErrorObjectNotFound): status = http.StatusNotFound case IsErrParamInvalid(err) || IsErrParamNotFound(err): status = http.StatusBadRequest diff --git a/fs/rc/params_test.go b/fs/rc/params_test.go index 3006f08ce..26f3153d9 100644 --- a/fs/rc/params_test.go +++ b/fs/rc/params_test.go @@ -1,13 +1,13 @@ package rc import ( + "errors" "fmt" "net/http" "net/http/httptest" "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/fs/rc/rcserver/rcserver.go b/fs/rc/rcserver/rcserver.go index 39498e388..3d7a79a5c 100644 --- a/fs/rc/rcserver/rcserver.go +++ b/fs/rc/rcserver/rcserver.go @@ -20,7 +20,6 @@ import ( "github.com/rclone/rclone/fs/rc/webgui" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/skratchdot/open-golang/open" @@ -138,7 +137,7 @@ func (s *Server) Serve() error { if s.files != nil { openURL, err := url.Parse(s.URL()) if err != nil { - return errors.Wrap(err, "invalid serving URL") + return fmt.Errorf("invalid serving URL: %w", err) } // Add username, password into the URL if they are set user, pass := s.opt.HTTPOptions.BasicUser, s.opt.HTTPOptions.BasicPass @@ -211,7 +210,7 @@ func (s *Server) handler(w http.ResponseWriter, r *http.Request) { case "GET", "HEAD": s.handleGet(w, r, path) default: - writeError(path, nil, w, errors.Errorf("method %q not allowed", r.Method), http.StatusMethodNotAllowed) + writeError(path, nil, w, fmt.Errorf("method %q not allowed", r.Method), http.StatusMethodNotAllowed) return } } @@ -225,7 +224,7 @@ func (s *Server) handlePost(w http.ResponseWriter, r *http.Request, path string) // Parse the POST and URL parameters into r.Form, for others r.Form will be empty value err := r.ParseForm() if err != nil { - writeError(path, nil, w, errors.Wrap(err, "failed to parse form/URL parameters"), http.StatusBadRequest) + writeError(path, nil, w, fmt.Errorf("failed to parse form/URL parameters: %w", err), http.StatusBadRequest) return } values = r.Form @@ -243,20 +242,20 @@ func (s *Server) handlePost(w http.ResponseWriter, r *http.Request, path string) if contentType == "application/json" { err := json.NewDecoder(r.Body).Decode(&in) if err != nil { - writeError(path, in, w, errors.Wrap(err, "failed to read input JSON"), http.StatusBadRequest) + writeError(path, in, w, fmt.Errorf("failed to read input JSON: %w", err), http.StatusBadRequest) return } } // Find the call call := rc.Calls.Get(path) if call == nil { - writeError(path, in, w, errors.Errorf("couldn't find method %q", path), http.StatusNotFound) + writeError(path, in, w, fmt.Errorf("couldn't find method %q", path), http.StatusNotFound) return } // Check to see if it requires authorisation if !s.opt.NoAuth && call.AuthRequired && !s.UsingAuth() { - writeError(path, in, w, errors.Errorf("authentication must be set up on the rc server to use %q or the --rc-no-auth flag must be in use", path), http.StatusForbidden) + writeError(path, in, w, fmt.Errorf("authentication must be set up on the rc server to use %q or the --rc-no-auth flag must be in use", path), http.StatusForbidden) return } @@ -317,14 +316,14 @@ func (s *Server) serveRoot(w http.ResponseWriter, r *http.Request) { func (s *Server) serveRemote(w http.ResponseWriter, r *http.Request, path string, fsName string) { f, err := cache.Get(s.ctx, fsName) if err != nil { - writeError(path, nil, w, errors.Wrap(err, "failed to make Fs"), http.StatusInternalServerError) + writeError(path, nil, w, fmt.Errorf("failed to make Fs: %w", err), http.StatusInternalServerError) return } if path == "" || strings.HasSuffix(path, "/") { path = strings.Trim(path, "/") entries, err := list.DirSorted(r.Context(), f, false, path) if err != nil { - writeError(path, nil, w, errors.Wrap(err, "failed to list directory"), http.StatusInternalServerError) + writeError(path, nil, w, fmt.Errorf("failed to list directory: %w", err), http.StatusInternalServerError) return } // Make the entries for display @@ -343,7 +342,7 @@ func (s *Server) serveRemote(w http.ResponseWriter, r *http.Request, path string path = strings.Trim(path, "/") o, err := f.NewObject(r.Context(), path) if err != nil { - writeError(path, nil, w, errors.Wrap(err, "failed to find object"), http.StatusInternalServerError) + writeError(path, nil, w, fmt.Errorf("failed to find object: %w", err), http.StatusInternalServerError) return } serve.Object(w, r, o) diff --git a/fs/rc/webgui/plugins.go b/fs/rc/webgui/plugins.go index 7bc22be54..3a97fd679 100644 --- a/fs/rc/webgui/plugins.go +++ b/fs/rc/webgui/plugins.go @@ -2,6 +2,7 @@ package webgui import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net/http" @@ -16,7 +17,6 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/rc/rcflags" - "github.com/rclone/rclone/lib/errors" ) // PackageJSON is the structure of package.json of a plugin diff --git a/fs/rc/webgui/webgui.go b/fs/rc/webgui/webgui.go index a272d73e6..ea37382ee 100644 --- a/fs/rc/webgui/webgui.go +++ b/fs/rc/webgui/webgui.go @@ -5,6 +5,7 @@ package webgui import ( "archive/zip" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -15,7 +16,6 @@ import ( "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/file" ) @@ -24,15 +24,15 @@ import ( func GetLatestReleaseURL(fetchURL string) (string, string, int, error) { resp, err := http.Get(fetchURL) if err != nil { - return "", "", 0, errors.Wrap(err, "failed getting latest release of rclone-webui") + return "", "", 0, fmt.Errorf("failed getting latest release of rclone-webui: %w", err) } defer fs.CheckClose(resp.Body, &err) if resp.StatusCode != http.StatusOK { - return "", "", 0, errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, fetchURL) + return "", "", 0, fmt.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, fetchURL) } results := gitHubRequest{} if err := json.NewDecoder(resp.Body).Decode(&results); err != nil { - return "", "", 0, errors.Wrap(err, "could not decode results from http request") + return "", "", 0, fmt.Errorf("could not decode results from http request: %w", err) } if len(results.Assets) < 1 { return "", "", 0, errors.New("could not find an asset in the release. " + @@ -63,7 +63,7 @@ func CheckAndDownloadWebGUIRelease(checkUpdate bool, forceUpdate bool, fetchURL // Get the latest release details WebUIURL, tag, size, err := GetLatestReleaseURL(fetchURL) if err != nil { - return errors.Wrap(err, "Error checking for web gui release update, skipping update") + return fmt.Errorf("Error checking for web gui release update, skipping update: %w", err) } dat, err := ioutil.ReadFile(tagPath) tagsMatch := false @@ -150,7 +150,7 @@ func DownloadFile(filepath string, url string) (err error) { } defer fs.CheckClose(resp.Body, &err) if resp.StatusCode != http.StatusOK { - return errors.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, url) + return fmt.Errorf("bad HTTP status %d (%s) when fetching %s", resp.StatusCode, resp.Status, url) } // Create the file diff --git a/fs/registry.go b/fs/registry.go index 24b4772bf..7ca447372 100644 --- a/fs/registry.go +++ b/fs/registry.go @@ -11,7 +11,6 @@ import ( "sort" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" ) @@ -260,7 +259,7 @@ func Find(name string) (*RegInfo, error) { return item, nil } } - return nil, errors.Errorf("didn't find backend called %q", name) + return nil, fmt.Errorf("didn't find backend called %q", name) } // MustFind looks for an Info object for the type name passed in diff --git a/fs/sizesuffix.go b/fs/sizesuffix.go index eda3c2368..04056b707 100644 --- a/fs/sizesuffix.go +++ b/fs/sizesuffix.go @@ -3,13 +3,12 @@ package fs // SizeSuffix is parsed by flag with K/M/G binary suffixes import ( "encoding/json" + "errors" "fmt" "math" "sort" "strconv" "strings" - - "github.com/pkg/errors" ) // SizeSuffix is an int64 with a friendly way of printing setting @@ -153,7 +152,7 @@ func (x *SizeSuffix) Set(s string) error { suffix = s[len(s)-3] suffixLen = 3 if multiplierFound, multiplier = x.multiplierFromSymbol(suffix); !multiplierFound { - return errors.Errorf("bad suffix %q", suffix) + return fmt.Errorf("bad suffix %q", suffix) } // Could also support SI form MB, and treat it equivalent to MiB, but perhaps better to reserve it for CountSuffix? //} else if len(s) > 1 { @@ -172,11 +171,11 @@ func (x *SizeSuffix) Set(s string) error { multiplierFound, multiplier = x.multiplierFromSymbol(suffix) } if !multiplierFound { - return errors.Errorf("bad suffix %q", suffix) + return fmt.Errorf("bad suffix %q", suffix) } default: if multiplierFound, multiplier = x.multiplierFromSymbol(suffix); !multiplierFound { - return errors.Errorf("bad suffix %q", suffix) + return fmt.Errorf("bad suffix %q", suffix) } } s = s[:len(s)-suffixLen] @@ -185,7 +184,7 @@ func (x *SizeSuffix) Set(s string) error { return err } if value < 0 { - return errors.Errorf("size can't be negative %q", s) + return fmt.Errorf("size can't be negative %q", s) } value *= multiplier *x = SizeSuffix(value) diff --git a/fs/sync/pipe.go b/fs/sync/pipe.go index d28527e7b..a2aa701bc 100644 --- a/fs/sync/pipe.go +++ b/fs/sync/pipe.go @@ -2,13 +2,13 @@ package sync import ( "context" + "fmt" "math/bits" "strconv" "strings" "sync" "github.com/aalpar/deheap" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" ) @@ -201,7 +201,7 @@ func newLess(orderBy string) (less lessFn, fraction int, err error) { return a.Src.ModTime(ctx).Before(b.Src.ModTime(ctx)) } default: - return nil, fraction, errors.Errorf("unknown --order-by comparison %q", parts[0]) + return nil, fraction, fmt.Errorf("unknown --order-by comparison %q", parts[0]) } descending := false if len(parts) > 1 { @@ -214,16 +214,16 @@ func newLess(orderBy string) (less lessFn, fraction int, err error) { if len(parts) > 2 { fraction, err = strconv.Atoi(parts[2]) if err != nil { - return nil, fraction, errors.Errorf("bad mixed fraction --order-by %q", parts[2]) + return nil, fraction, fmt.Errorf("bad mixed fraction --order-by %q", parts[2]) } } default: - return nil, fraction, errors.Errorf("unknown --order-by sort direction %q", parts[1]) + return nil, fraction, fmt.Errorf("unknown --order-by sort direction %q", parts[1]) } } if (fraction >= 0 && len(parts) > 3) || (fraction < 0 && len(parts) > 2) { - return nil, fraction, errors.Errorf("bad --order-by string %q", orderBy) + return nil, fraction, fmt.Errorf("bad --order-by string %q", orderBy) } if descending { oldLess := less diff --git a/fs/sync/sync.go b/fs/sync/sync.go index 96290e0a1..4c9e0f959 100644 --- a/fs/sync/sync.go +++ b/fs/sync/sync.go @@ -3,6 +3,7 @@ package sync import ( "context" + "errors" "fmt" "path" "sort" @@ -10,7 +11,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" @@ -645,7 +645,7 @@ func parseTrackRenamesStrategy(strategies string) (strategy trackRenamesStrategy case "size": // ignore default: - return strategy, errors.Errorf("unknown track renames strategy %q", s) + return strategy, fmt.Errorf("unknown track renames strategy %q", s) } } return strategy, nil diff --git a/fs/sync/sync_test.go b/fs/sync/sync_test.go index c5724a9cc..d3f2e66b9 100644 --- a/fs/sync/sync_test.go +++ b/fs/sync/sync_test.go @@ -4,13 +4,13 @@ package sync import ( "context" + "errors" "fmt" "runtime" "strings" "testing" "time" - "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/all" // import all backends "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" @@ -1059,7 +1059,7 @@ func TestSyncWithMaxDuration(t *testing.T) { accounting.GlobalStats().ResetCounters() startTime := time.Now() err := Sync(ctx, r.Fremote, r.Flocal, false) - require.Equal(t, context.DeadlineExceeded, errors.Cause(err)) + require.True(t, errors.Is(err, context.DeadlineExceeded)) elapsed := time.Since(startTime) maxTransferTime := (time.Duration(len(testFiles)) * 60 * time.Second) / time.Duration(bytesPerSecond) @@ -2091,7 +2091,7 @@ func testSyncConcurrent(t *testing.T, subtest string) { fstest.CheckItems(t, r.Fremote, itemsBefore...) stats.ResetErrors() err := Sync(ctx, r.Fremote, r.Flocal, false) - if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles { + if errors.Is(err, fs.ErrorCantUploadEmptyFiles) { t.Skipf("Skip test because remote cannot upload empty files") } assert.NoError(t, err, "Sync must not return a error") diff --git a/fs/tristate.go b/fs/tristate.go index d35980e03..d03926a07 100644 --- a/fs/tristate.go +++ b/fs/tristate.go @@ -5,8 +5,6 @@ import ( "fmt" "strconv" "strings" - - "github.com/pkg/errors" ) // Tristate is a boolean that can has the states, true, false and @@ -36,7 +34,7 @@ func (t *Tristate) Set(s string) error { } value, err := strconv.ParseBool(s) if err != nil { - return errors.Wrapf(err, "failed to parse Tristate %q", s) + return fmt.Errorf("failed to parse Tristate %q: %w", s, err) } t.Value = value t.Valid = true diff --git a/fs/walk/walk.go b/fs/walk/walk.go index f3d76f298..56418b522 100644 --- a/fs/walk/walk.go +++ b/fs/walk/walk.go @@ -3,13 +3,14 @@ package walk import ( "context" + "errors" + "fmt" "path" "sort" "strings" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/dirtree" "github.com/rclone/rclone/fs/filter" @@ -244,7 +245,7 @@ func (dm *dirMap) addEntries(entries fs.DirEntries) error { case fs.Directory: dm.add(x.Remote(), true) default: - return errors.Errorf("unknown object type %T", entry) + return fmt.Errorf("unknown object type %T", entry) } } return nil @@ -315,7 +316,7 @@ func listR(ctx context.Context, f fs.Fs, path string, includeAll bool, listType return err } default: - return errors.Errorf("unknown object type %T", entry) + return fmt.Errorf("unknown object type %T", entry) } if include { filteredEntries = append(filteredEntries, entry) @@ -514,7 +515,7 @@ func walkRDirTree(ctx context.Context, f fs.Fs, startPath string, includeAll boo fs.Debugf(x, "Excluded from sync (and deletion)") } default: - return errors.Errorf("unknown object type %T", entry) + return fmt.Errorf("unknown object type %T", entry) } } return nil diff --git a/fs/walk/walk_test.go b/fs/walk/walk_test.go index c8da2e7a3..79ccbf373 100644 --- a/fs/walk/walk_test.go +++ b/fs/walk/walk_test.go @@ -2,13 +2,13 @@ package walk import ( "context" + "errors" "fmt" "io" "strings" "sync" "testing" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" _ "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go index 2fb0ba4f4..3c9984926 100644 --- a/fstest/fstests/fstests.go +++ b/fstest/fstests/fstests.go @@ -9,6 +9,7 @@ package fstests import ( "bytes" "context" + "errors" "fmt" "io" "io/ioutil" @@ -23,7 +24,6 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/fserrors" @@ -874,7 +874,7 @@ func Run(t *testing.T, opt *Opt) { var objNames, dirNames []string for i := 1; i <= *fstest.ListRetries; i++ { objs, dirs, err := walk.GetAll(ctx, f, dir, true, 1) - if errors.Cause(err) == fs.ErrorDirNotFound { + if errors.Is(err, fs.ErrorDirNotFound) { objs, dirs, err = walk.GetAll(ctx, f, dir, true, 1) } require.NoError(t, err) @@ -1223,7 +1223,7 @@ func Run(t *testing.T, opt *Opt) { // check remotes // remote should not exist here _, err = f.List(ctx, "") - assert.Equal(t, fs.ErrorDirNotFound, errors.Cause(err)) + assert.True(t, errors.Is(err, fs.ErrorDirNotFound)) //fstest.CheckListingWithPrecision(t, remote, []fstest.Item{}, []string{}, remote.Precision()) file1Copy := file1 file1Copy.Path = path.Join(newName, file1.Path) @@ -1618,7 +1618,7 @@ func Run(t *testing.T, opt *Opt) { // sharing directory for the first time path := path.Dir(file2.Path) link3, err := doPublicLink(ctx, path, expiry, false) - if err != nil && (errors.Cause(err) == fs.ErrorCantShareDirectories || errors.Cause(err) == fs.ErrorObjectNotFound) { + if err != nil && (errors.Is(err, fs.ErrorCantShareDirectories) || errors.Is(err, fs.ErrorObjectNotFound)) { t.Log("skipping directory tests as not supported on this backend") } else { require.NoError(t, err) @@ -1953,7 +1953,7 @@ func Run(t *testing.T, opt *Opt) { // Purge the folder err = operations.Purge(ctx, f, "") - if errors.Cause(err) != fs.ErrorDirNotFound { + if !errors.Is(err, fs.ErrorDirNotFound) { require.NoError(t, err) } purged = true @@ -1963,7 +1963,7 @@ func Run(t *testing.T, opt *Opt) { if !isBucketBasedButNotRoot(f) { err = operations.Purge(ctx, f, "") assert.Error(t, err, "Expecting error after on second purge") - if errors.Cause(err) != fs.ErrorDirNotFound { + if !errors.Is(err, fs.ErrorDirNotFound) { t.Log("Warning: this should produce fs.ErrorDirNotFound") } } diff --git a/fstest/test_all/clean.go b/fstest/test_all/clean.go index 7cda57093..c4d22a8a4 100644 --- a/fstest/test_all/clean.go +++ b/fstest/test_all/clean.go @@ -4,10 +4,10 @@ package main import ( "context" + "fmt" "log" "regexp" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/list" "github.com/rclone/rclone/fs/operations" @@ -48,14 +48,14 @@ func cleanFs(ctx context.Context, remote string, cleanup bool) error { log.Printf("Purging %s", fullPath) dir, err := fs.NewFs(context.Background(), fullPath) if err != nil { - err = errors.Wrap(err, "NewFs failed") + err = fmt.Errorf("NewFs failed: %w", err) lastErr = err fs.Errorf(fullPath, "%v", err) return nil } err = operations.Purge(ctx, dir, "") if err != nil { - err = errors.Wrap(err, "Purge failed") + err = fmt.Errorf("Purge failed: %w", err) lastErr = err fs.Errorf(dir, "%v", err) return nil diff --git a/fstest/test_all/config.go b/fstest/test_all/config.go index 31a55a2a5..62d8c057c 100644 --- a/fstest/test_all/config.go +++ b/fstest/test_all/config.go @@ -3,11 +3,11 @@ package main import ( + "fmt" "io/ioutil" "log" "path" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" yaml "gopkg.in/yaml.v2" ) @@ -112,12 +112,12 @@ type Config struct { func NewConfig(configFile string) (*Config, error) { d, err := ioutil.ReadFile(configFile) if err != nil { - return nil, errors.Wrap(err, "failed to read config file") + return nil, fmt.Errorf("failed to read config file: %w", err) } config := &Config{} err = yaml.Unmarshal(d, &config) if err != nil { - return nil, errors.Wrap(err, "failed to parse config file") + return nil, fmt.Errorf("failed to parse config file: %w", err) } // d, err = yaml.Marshal(&config) // if err != nil { diff --git a/fstest/testserver/testserver.go b/fstest/testserver/testserver.go index bdcf05131..005096e85 100644 --- a/fstest/testserver/testserver.go +++ b/fstest/testserver/testserver.go @@ -3,6 +3,7 @@ package testserver import ( "bytes" + "errors" "fmt" "net" "os" @@ -13,7 +14,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fspath" ) @@ -52,7 +52,7 @@ func run(name, command string) (out []byte, err error) { cmd := exec.Command(cmdPath, command) out, err = cmd.CombinedOutput() if err != nil { - err = errors.Wrapf(err, "failed to run %s %s\n%s", cmdPath, command, string(out)) + err = fmt.Errorf("failed to run %s %s\n%s: %w", cmdPath, command, string(out), err) } return out, err } @@ -112,7 +112,7 @@ func start(name string) error { } time.Sleep(time.Second) } - return errors.Errorf("failed to connect to %q on %q", name, connect) + return fmt.Errorf("failed to connect to %q on %q", name, connect) } // Start starts the named test server which can be stopped by the diff --git a/go.mod b/go.mod index b8c0219cf..74f897418 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,6 @@ require ( github.com/ncw/swift/v2 v2.0.1 github.com/nsf/termbox-go v1.1.1 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.13.2 github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.11.0 diff --git a/lib/daemonize/daemon_other.go b/lib/daemonize/daemon_other.go index 70e4a6df5..788d034e0 100644 --- a/lib/daemonize/daemon_other.go +++ b/lib/daemonize/daemon_other.go @@ -6,13 +6,12 @@ package daemonize import ( + "fmt" "os" "runtime" - - "github.com/pkg/errors" ) // StartDaemon runs background twin of current process. func StartDaemon(args []string) (*os.Process, error) { - return nil, errors.Errorf("background mode is not supported on %s platform", runtime.GOOS) + return nil, fmt.Errorf("background mode is not supported on %s platform", runtime.GOOS) } diff --git a/lib/dircache/dircache.go b/lib/dircache/dircache.go index a8c9d3a6f..05766335d 100644 --- a/lib/dircache/dircache.go +++ b/lib/dircache/dircache.go @@ -7,12 +7,12 @@ package dircache import ( "bytes" "context" + "errors" "fmt" "path" "strings" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" ) @@ -241,7 +241,7 @@ func (dc *DirCache) _findDir(ctx context.Context, path string, create bool) (pat if create { pathID, err = dc.fs.CreateDir(ctx, parentPathID, leaf) if err != nil { - return "", errors.Wrap(err, "failed to make directory") + return "", fmt.Errorf("failed to make directory: %w", err) } } else { return "", fs.ErrorDirNotFound diff --git a/lib/errors/errors.go b/lib/errors/errors.go index 6338440c4..2d9c6b93f 100644 --- a/lib/errors/errors.go +++ b/lib/errors/errors.go @@ -1,22 +1,9 @@ package errors import ( - "errors" - "fmt" "reflect" ) -// New returns an error that formats as the given text. -func New(text string) error { - return errors.New(text) -} - -// Errorf formats according to a format specifier and returns the string -// as a value that satisfies error. -func Errorf(format string, a ...interface{}) error { - return fmt.Errorf(format, a...) -} - // WalkFunc is the signature of the Walk callback function. The function gets the // current error in the chain and should return true if the chain processing // should be aborted. @@ -27,7 +14,6 @@ type WalkFunc func(error) bool // is stopped and no further calls will be made. // // The next error in the chain is determined by the following rules: -// - If the current error has a `Cause() error` method (github.com/pkg/errors), // the return value of this method is used. // - If the current error has a `Unwrap() error` method (golang.org/x/xerrors), // the return value of this method is used. diff --git a/lib/errors/errors_test.go b/lib/errors/errors_test.go index 5ef92c683..c208a5a2e 100644 --- a/lib/errors/errors_test.go +++ b/lib/errors/errors_test.go @@ -1,12 +1,13 @@ package errors_test import ( + "errors" "fmt" "testing" "github.com/stretchr/testify/assert" - "github.com/rclone/rclone/lib/errors" + liberrors "github.com/rclone/rclone/lib/errors" ) func TestWalk(t *testing.T) { @@ -43,7 +44,7 @@ func TestWalk(t *testing.T) { } { var last error calls := 0 - errors.Walk(test.err, func(err error) bool { + liberrors.Walk(test.err, func(err error) bool { calls++ last = err _, stop := err.(stopError) diff --git a/lib/file/preallocate_windows.go b/lib/file/preallocate_windows.go index afa33fe4b..49352356a 100644 --- a/lib/file/preallocate_windows.go +++ b/lib/file/preallocate_windows.go @@ -4,12 +4,12 @@ package file import ( + "fmt" "os" "sync" "syscall" "unsafe" - "github.com/pkg/errors" "golang.org/x/sys/windows" ) @@ -63,13 +63,13 @@ func PreAllocate(size int64, out *os.File) error { uintptr(3), // FileFsSizeInformation ) if e1 != nil && e1 != syscall.Errno(0) { - return errors.Wrap(e1, "preAllocate NtQueryVolumeInformationFile failed") + return fmt.Errorf("preAllocate NtQueryVolumeInformationFile failed: %w", e1) } // Calculate the allocation size clusterSize := uint64(fsSizeInfo.BytesPerSector) * uint64(fsSizeInfo.SectorsPerAllocationUnit) if clusterSize <= 0 { - return errors.Errorf("preAllocate clusterSize %d <= 0", clusterSize) + return fmt.Errorf("preAllocate clusterSize %d <= 0", clusterSize) } allocInfo.AllocationSize = (1 + uint64(size-1)/clusterSize) * clusterSize @@ -85,7 +85,7 @@ func PreAllocate(size int64, out *os.File) error { if e1 == syscall.Errno(windows.ERROR_DISK_FULL) || e1 == syscall.Errno(windows.ERROR_HANDLE_DISK_FULL) { return ErrDiskFull } - return errors.Wrap(e1, "preAllocate NtSetInformationFile failed") + return fmt.Errorf("preAllocate NtSetInformationFile failed: %w", e1) } return nil @@ -104,7 +104,7 @@ func SetSparse(out *os.File) error { var bytesReturned uint32 err := syscall.DeviceIoControl(syscall.Handle(out.Fd()), FSCTL_SET_SPARSE, nil, 0, nil, 0, &bytesReturned, nil) if err != nil { - return errors.Wrap(err, "DeviceIoControl FSCTL_SET_SPARSE") + return fmt.Errorf("DeviceIoControl FSCTL_SET_SPARSE: %w", err) } return nil } diff --git a/lib/http/http.go b/lib/http/http.go index abf3b76d4..d6ff1452a 100644 --- a/lib/http/http.go +++ b/lib/http/http.go @@ -5,6 +5,7 @@ import ( "context" "crypto/tls" "crypto/x509" + "errors" "fmt" "io/ioutil" "log" @@ -15,7 +16,6 @@ import ( "time" "github.com/go-chi/chi/v5" - "github.com/pkg/errors" "github.com/rclone/rclone/fs/config/flags" "github.com/spf13/pflag" ) diff --git a/lib/jwtutil/jwtutil.go b/lib/jwtutil/jwtutil.go index f99b36b97..8473c45bd 100644 --- a/lib/jwtutil/jwtutil.go +++ b/lib/jwtutil/jwtutil.go @@ -6,13 +6,14 @@ import ( "crypto/rsa" "encoding/hex" "encoding/json" + "errors" + "fmt" "io" "io/ioutil" "net/http" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/lib/oauthutil" @@ -34,11 +35,11 @@ func RandomHex(n int) (string, error) { func Config(id, name string, claims *jws.ClaimSet, header *jws.Header, queryParams map[string]string, privateKey *rsa.PrivateKey, m configmap.Mapper, client *http.Client) (err error) { payload, err := jws.Encode(header, claims, privateKey) if err != nil { - return errors.Wrap(err, "jwtutil: failed to encode payload") + return fmt.Errorf("jwtutil: failed to encode payload: %w", err) } req, err := http.NewRequest("POST", claims.Aud, nil) if err != nil { - return errors.Wrap(err, "jwtutil: failed to create new request") + return fmt.Errorf("jwtutil: failed to create new request: %w", err) } q := req.URL.Query() q.Add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer") @@ -50,13 +51,13 @@ func Config(id, name string, claims *jws.ClaimSet, header *jws.Header, queryPara req, err = http.NewRequest("POST", claims.Aud, bytes.NewBuffer([]byte(queryString))) if err != nil { - return errors.Wrap(err, "jwtutil: failed to create new request") + return fmt.Errorf("jwtutil: failed to create new request: %w", err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { - return errors.Wrap(err, "jwtutil: failed making auth request") + return fmt.Errorf("jwtutil: failed making auth request: %w", err) } s, err := bodyToString(resp.Body) @@ -65,12 +66,12 @@ func Config(id, name string, claims *jws.ClaimSet, header *jws.Header, queryPara } if resp.StatusCode != 200 { err = errors.New(resp.Status) - return errors.Wrap(err, "jwtutil: failed making auth request") + return fmt.Errorf("jwtutil: failed making auth request: %w", err) } defer func() { deferedErr := resp.Body.Close() if deferedErr != nil { - err = errors.Wrap(err, "jwtutil: failed to close resp.Body") + err = fmt.Errorf("jwtutil: failed to close resp.Body: %w", err) } }() @@ -80,7 +81,7 @@ func Config(id, name string, claims *jws.ClaimSet, header *jws.Header, queryPara err = errors.New("No AccessToken in Response") } if err != nil { - return errors.Wrap(err, "jwtutil: failed to get token") + return fmt.Errorf("jwtutil: failed to get token: %w", err) } token := &oauth2.Token{ AccessToken: result.AccessToken, diff --git a/lib/kv/bolt.go b/lib/kv/bolt.go index 4b0efc7dc..5f9f3d7a6 100644 --- a/lib/kv/bolt.go +++ b/lib/kv/bolt.go @@ -5,13 +5,13 @@ package kv import ( "context" + "fmt" "os" "path/filepath" "strings" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/lib/encoder" @@ -101,7 +101,7 @@ func Start(ctx context.Context, facility string, f fs.Fs) (*DB, error) { } if err = db.open(ctx, false); err != nil && err != ErrEmpty { - return nil, errors.Wrapf(err, "cannot open db: %s", db.path) + return nil, fmt.Errorf("cannot open db: %s: %w", db.path, err) } dbMap[name] = db diff --git a/lib/kv/types.go b/lib/kv/types.go index f21957976..601dd21da 100644 --- a/lib/kv/types.go +++ b/lib/kv/types.go @@ -2,8 +2,7 @@ package kv import ( "context" - - "github.com/pkg/errors" + "errors" ) // package errors diff --git a/lib/mmap/mmap_unix.go b/lib/mmap/mmap_unix.go index f5c7f40c2..be7cf195c 100644 --- a/lib/mmap/mmap_unix.go +++ b/lib/mmap/mmap_unix.go @@ -7,7 +7,8 @@ package mmap import ( - "github.com/pkg/errors" + "fmt" + "golang.org/x/sys/unix" ) @@ -17,7 +18,7 @@ import ( func Alloc(size int) ([]byte, error) { mem, err := unix.Mmap(-1, 0, size, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_PRIVATE|unix.MAP_ANON) if err != nil { - return nil, errors.Wrap(err, "mmap: failed to allocate memory for buffer") + return nil, fmt.Errorf("mmap: failed to allocate memory for buffer: %w", err) } return mem, nil } @@ -28,7 +29,7 @@ func Alloc(size int) ([]byte, error) { func Free(mem []byte) error { err := unix.Munmap(mem) if err != nil { - return errors.Wrap(err, "mmap: failed to unmap memory") + return fmt.Errorf("mmap: failed to unmap memory: %w", err) } return nil } diff --git a/lib/mmap/mmap_windows.go b/lib/mmap/mmap_windows.go index ce57aadef..5c45ac89b 100644 --- a/lib/mmap/mmap_windows.go +++ b/lib/mmap/mmap_windows.go @@ -7,10 +7,10 @@ package mmap import ( + "fmt" "reflect" "unsafe" - "github.com/pkg/errors" "golang.org/x/sys/windows" ) @@ -20,7 +20,7 @@ import ( func Alloc(size int) ([]byte, error) { p, err := windows.VirtualAlloc(0, uintptr(size), windows.MEM_COMMIT, windows.PAGE_READWRITE) if err != nil { - return nil, errors.Wrap(err, "mmap: failed to allocate memory for buffer") + return nil, fmt.Errorf("mmap: failed to allocate memory for buffer: %w", err) } var mem []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&mem)) @@ -37,7 +37,7 @@ func Free(mem []byte) error { sh := (*reflect.SliceHeader)(unsafe.Pointer(&mem)) err := windows.VirtualFree(sh.Data, 0, windows.MEM_RELEASE) if err != nil { - return errors.Wrap(err, "mmap: failed to unmap memory") + return fmt.Errorf("mmap: failed to unmap memory: %w", err) } return nil } diff --git a/lib/oauthutil/oauthutil.go b/lib/oauthutil/oauthutil.go index fba29a937..2203a0e47 100644 --- a/lib/oauthutil/oauthutil.go +++ b/lib/oauthutil/oauthutil.go @@ -3,6 +3,7 @@ package oauthutil import ( "context" "encoding/json" + "errors" "fmt" "html/template" "net" @@ -12,7 +13,6 @@ import ( "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/config/configmap" @@ -110,7 +110,7 @@ type oldToken struct { func GetToken(name string, m configmap.Mapper) (*oauth2.Token, error) { tokenString, ok := m.Get(config.ConfigToken) if !ok || tokenString == "" { - return nil, errors.Errorf("empty token found - please run \"rclone config reconnect %s:\"", name) + return nil, fmt.Errorf("empty token found - please run \"rclone config reconnect %s:\"", name) } token := new(oauth2.Token) err := json.Unmarshal([]byte(tokenString), token) @@ -245,7 +245,7 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) { time.Sleep(1 * time.Second) } if err != nil { - return nil, errors.Wrapf(err, "couldn't fetch token - maybe it has expired? - refresh with \"rclone config reconnect %s:\"", ts.name) + return nil, fmt.Errorf("couldn't fetch token - maybe it has expired? - refresh with \"rclone config reconnect %s:\": %w", ts.name, err) } changed = changed || (*token != *ts.token) ts.token = token @@ -256,7 +256,7 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) { } err = PutToken(ts.name, ts.m, token, false) if err != nil { - return nil, errors.Wrap(err, "couldn't store token") + return nil, fmt.Errorf("couldn't store token: %w", err) } } return token, nil @@ -442,7 +442,7 @@ func ConfigOAuth(ctx context.Context, name string, m configmap.Mapper, ri *fs.Re } opt, ok := out.OAuth.(*Options) if !ok { - return nil, errors.Errorf("internal error: oauth failed: wrong type in config: %T", out.OAuth) + return nil, fmt.Errorf("internal error: oauth failed: wrong type in config: %T", out.OAuth) } if opt.OAuth2Config == nil { return nil, errors.New("internal error: oauth failed: OAuth2Config not set") @@ -499,7 +499,7 @@ version recommended): // Encode them into a string mCopyString, err := inM.Encode() if err != nil { - return nil, errors.Wrap(err, "oauthutil authorize encode") + return nil, fmt.Errorf("oauthutil authorize encode: %w", err) } // Write what the user has to do if len(mCopyString) > 0 { @@ -547,7 +547,7 @@ version recommended): oauthConfig = fixRedirect(oauthConfig) code, err = configSetup(ctx, ri.Name, name, m, oauthConfig, opt) if err != nil { - return nil, errors.Wrap(err, "config failed to refresh token") + return nil, fmt.Errorf("config failed to refresh token: %w", err) } } err = configExchange(ctx, name, m, oauthConfig, code) @@ -560,7 +560,7 @@ version recommended): _, returnState := fs.StatePop(stateParams) return fs.ConfigGoto(returnState) } - return nil, errors.Errorf("unknown internal oauth state %q", state) + return nil, fmt.Errorf("unknown internal oauth state %q", state) } func init() { @@ -626,7 +626,7 @@ func configSetup(ctx context.Context, id, name string, m configmap.Mapper, oauth server := newAuthServer(opt, bindAddress, state, authURL) err = server.Init() if err != nil { - return "", errors.Wrap(err, "failed to start auth webserver") + return "", fmt.Errorf("failed to start auth webserver: %w", err) } go server.Serve() defer server.Stop() @@ -662,7 +662,7 @@ func configExchange(ctx context.Context, name string, m configmap.Mapper, oauthC ctx = Context(ctx, fshttp.NewClient(ctx)) token, err := oauthConfig.Exchange(ctx, code) if err != nil { - return errors.Wrap(err, "failed to get token") + return fmt.Errorf("failed to get token: %w", err) } return PutToken(name, m, token, true) } diff --git a/lib/pacer/pacer.go b/lib/pacer/pacer.go index dffa803f9..0257d70da 100644 --- a/lib/pacer/pacer.go +++ b/lib/pacer/pacer.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "github.com/rclone/rclone/lib/errors" + liberrors "github.com/rclone/rclone/lib/errors" ) // State represents the public Pacer state that will be passed to the @@ -253,7 +253,7 @@ func RetryAfterError(err error, retryAfter time.Duration) error { // IsRetryAfter returns true if the error or any of it's Cause's is an error // returned by RetryAfterError. It also returns the associated Duration if possible. func IsRetryAfter(err error) (retryAfter time.Duration, isRetryAfter bool) { - errors.Walk(err, func(err error) bool { + liberrors.Walk(err, func(err error) bool { if r, ok := err.(*retryAfterError); ok { retryAfter, isRetryAfter = r.retryAfter, true return true diff --git a/lib/pacer/pacer_test.go b/lib/pacer/pacer_test.go index 6159acd4e..11aebb4ab 100644 --- a/lib/pacer/pacer_test.go +++ b/lib/pacer/pacer_test.go @@ -1,11 +1,11 @@ package pacer import ( + "errors" "sync" "testing" "time" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/lib/random/random.go b/lib/random/random.go index 30198bdd4..08e752b84 100644 --- a/lib/random/random.go +++ b/lib/random/random.go @@ -5,9 +5,8 @@ import ( cryptorand "crypto/rand" "encoding/base64" "encoding/binary" + "fmt" mathrand "math/rand" - - "github.com/pkg/errors" ) // StringFn create a random string for test purposes using the random @@ -53,10 +52,10 @@ func Password(bits int) (password string, err error) { var pw = make([]byte, bytes) n, err := cryptorand.Read(pw) if err != nil { - return "", errors.Wrap(err, "password read failed") + return "", fmt.Errorf("password read failed: %w", err) } if n != bytes { - return "", errors.Errorf("password short read: %d", n) + return "", fmt.Errorf("password short read: %d", n) } password = base64.RawURLEncoding.EncodeToString(pw) return password, nil @@ -72,7 +71,7 @@ func Seed() error { var seed int64 err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed) if err != nil { - return errors.Wrap(err, "failed to read random seed") + return fmt.Errorf("failed to read random seed: %w", err) } mathrand.Seed(seed) return nil diff --git a/lib/readers/error_test.go b/lib/readers/error_test.go index 0231618b9..e8c73f980 100644 --- a/lib/readers/error_test.go +++ b/lib/readers/error_test.go @@ -1,9 +1,9 @@ package readers import ( + "errors" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/lib/readers/noclose_test.go b/lib/readers/noclose_test.go index da784425c..e954d9c72 100644 --- a/lib/readers/noclose_test.go +++ b/lib/readers/noclose_test.go @@ -1,10 +1,10 @@ package readers import ( + "errors" "io" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/lib/readers/pattern_reader.go b/lib/readers/pattern_reader.go index a480dc185..edceef24d 100644 --- a/lib/readers/pattern_reader.go +++ b/lib/readers/pattern_reader.go @@ -1,9 +1,8 @@ package readers import ( + "errors" "io" - - "github.com/pkg/errors" ) // This is the smallest prime less than 256 diff --git a/lib/readers/repeatable.go b/lib/readers/repeatable.go index e61b083d8..73de3fe90 100644 --- a/lib/readers/repeatable.go +++ b/lib/readers/repeatable.go @@ -1,10 +1,9 @@ package readers import ( + "errors" "io" "sync" - - "github.com/pkg/errors" ) // A RepeatableReader implements the io.ReadSeeker it allow to seek cached data diff --git a/lib/rest/rest.go b/lib/rest/rest.go index 4490d617a..e534b0d1e 100644 --- a/lib/rest/rest.go +++ b/lib/rest/rest.go @@ -8,6 +8,8 @@ import ( "context" "encoding/json" "encoding/xml" + "errors" + "fmt" "io" "io/ioutil" "mime/multipart" @@ -15,7 +17,6 @@ import ( "net/url" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/lib/readers" ) @@ -51,9 +52,9 @@ func ReadBody(resp *http.Response) (result []byte, err error) { func defaultErrorHandler(resp *http.Response) (err error) { body, err := ReadBody(resp) if err != nil { - return errors.Wrap(err, "error reading error out of body") + return fmt.Errorf("error reading error out of body: %w", err) } - return errors.Errorf("HTTP error %v (%v) returned body: %q", resp.StatusCode, resp.Status, body) + return fmt.Errorf("HTTP error %v (%v) returned body: %q", resp.StatusCode, resp.Status, body) } // SetErrorHandler sets the handler to decode an error response when @@ -272,7 +273,7 @@ func (api *Client) Call(ctx context.Context, opts *Opts) (resp *http.Response, e err = api.signer(req) api.mu.RLock() if err != nil { - return nil, errors.Wrap(err, "signer failed") + return nil, fmt.Errorf("signer failed: %w", err) } } api.mu.RUnlock() @@ -286,7 +287,7 @@ func (api *Client) Call(ctx context.Context, opts *Opts) (resp *http.Response, e err = api.errorHandler(resp) if err.Error() == "" { // replace empty errors with something - err = errors.Errorf("http error %d: %v", resp.StatusCode, resp.Status) + err = fmt.Errorf("http error %d: %v", resp.StatusCode, resp.Status) } return resp, err } @@ -364,7 +365,7 @@ func MultipartUpload(ctx context.Context, in io.Reader, params url.Values, conte for _, val := range vals { err = writer.WriteField(key, val) if err != nil { - _ = bodyWriter.CloseWithError(errors.Wrap(err, "create metadata part")) + _ = bodyWriter.CloseWithError(fmt.Errorf("create metadata part: %w", err)) return } } @@ -373,20 +374,20 @@ func MultipartUpload(ctx context.Context, in io.Reader, params url.Values, conte if in != nil { part, err := writer.CreateFormFile(contentName, fileName) if err != nil { - _ = bodyWriter.CloseWithError(errors.Wrap(err, "failed to create form file")) + _ = bodyWriter.CloseWithError(fmt.Errorf("failed to create form file: %w", err)) return } _, err = io.Copy(part, in) if err != nil { - _ = bodyWriter.CloseWithError(errors.Wrap(err, "failed to copy data")) + _ = bodyWriter.CloseWithError(fmt.Errorf("failed to copy data: %w", err)) return } } err = writer.Close() if err != nil { - _ = bodyWriter.CloseWithError(errors.Wrap(err, "failed to close form")) + _ = bodyWriter.CloseWithError(fmt.Errorf("failed to close form: %w", err)) return } diff --git a/lib/rest/url.go b/lib/rest/url.go index 07ce15958..4a1d71390 100644 --- a/lib/rest/url.go +++ b/lib/rest/url.go @@ -1,9 +1,8 @@ package rest import ( + "fmt" "net/url" - - "github.com/pkg/errors" ) // URLJoin joins a URL and a path returning a new URL @@ -12,7 +11,7 @@ import ( func URLJoin(base *url.URL, path string) (*url.URL, error) { rel, err := url.Parse(path) if err != nil { - return nil, errors.Wrapf(err, "Error parsing %q as URL", path) + return nil, fmt.Errorf("Error parsing %q as URL: %w", path, err) } return base.ResolveReference(rel), nil } diff --git a/librclone/librclone/librclone.go b/librclone/librclone/librclone.go index dabb02f0d..21c5aa5d5 100644 --- a/librclone/librclone/librclone.go +++ b/librclone/librclone/librclone.go @@ -15,7 +15,6 @@ import ( "runtime/debug" "strings" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/config/configfile" @@ -91,23 +90,23 @@ func RPC(method string, input string) (output string, status int) { // create a buffer to capture the output err := json.NewDecoder(strings.NewReader(input)).Decode(&in) if err != nil { - return writeError(method, in, errors.Wrap(err, "failed to read input JSON"), http.StatusBadRequest) + return writeError(method, in, fmt.Errorf("failed to read input JSON: %w", err), http.StatusBadRequest) } // Find the call call := rc.Calls.Get(method) if call == nil { - return writeError(method, in, errors.Errorf("couldn't find method %q", method), http.StatusNotFound) + return writeError(method, in, fmt.Errorf("couldn't find method %q", method), http.StatusNotFound) } // TODO: handle these cases if call.NeedsRequest { - return writeError(method, in, errors.Errorf("method %q needs request, not supported", method), http.StatusNotFound) + return writeError(method, in, fmt.Errorf("method %q needs request, not supported", method), http.StatusNotFound) // Add the request to RC //in["_request"] = r } if call.NeedsResponse { - return writeError(method, in, errors.Errorf("method %q need response, not supported", method), http.StatusNotFound) + return writeError(method, in, fmt.Errorf("method %q need response, not supported", method), http.StatusNotFound) //in["_response"] = w } diff --git a/vfs/dir.go b/vfs/dir.go index 755fde807..2b2eda5a2 100644 --- a/vfs/dir.go +++ b/vfs/dir.go @@ -11,7 +11,6 @@ import ( "sync/atomic" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/dirtree" "github.com/rclone/rclone/fs/list" @@ -651,7 +650,7 @@ func (d *Dir) _readDirFromEntries(entries fs.DirEntries, dirTree dirtree.DirTree } } default: - err = errors.Errorf("unknown type %T", item) + err = fmt.Errorf("unknown type %T", item) fs.Errorf(d, "readDir error: %v", err) return err } @@ -712,7 +711,7 @@ func (d *Dir) stat(leaf string) (Node, error) { if strings.ToLower(name) == leafLower { if ok { // duplicate case insensitive match is an error - return nil, errors.Errorf("duplicate filename %q detected with --vfs-case-insensitive set", leaf) + return nil, fmt.Errorf("duplicate filename %q detected with --vfs-case-insensitive set", leaf) } // found a case insensitive match ok = true @@ -1003,14 +1002,14 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error { return err } } else { - err := errors.Errorf("Fs %q can't rename file that is not a vfs.File", d.f) + err := fmt.Errorf("Fs %q can't rename file that is not a vfs.File", d.f) fs.Errorf(oldPath, "Dir.Rename error: %v", err) return err } case fs.Directory: features := d.f.Features() if features.DirMove == nil && features.Move == nil && features.Copy == nil { - err := errors.Errorf("Fs %q can't rename directories (no DirMove, Move or Copy)", d.f) + err := fmt.Errorf("Fs %q can't rename directories (no DirMove, Move or Copy)", d.f) fs.Errorf(oldPath, "Dir.Rename error: %v", err) return err } @@ -1030,7 +1029,7 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error { } } default: - err = errors.Errorf("unknown type %T", oldNode) + err = fmt.Errorf("unknown type %T", oldNode) fs.Errorf(d.path, "Dir.Rename error: %v", err) return err } diff --git a/vfs/file.go b/vfs/file.go index d890b1f54..4c4fc214a 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -2,13 +2,14 @@ package vfs import ( "context" + "errors" + "fmt" "os" "path" "sync" "sync/atomic" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/log" "github.com/rclone/rclone/fs/operations" @@ -166,7 +167,7 @@ func (f *File) rename(ctx context.Context, destDir *Dir, newName string) error { f.mu.RUnlock() if features := d.Fs().Features(); features.Move == nil && features.Copy == nil { - err := errors.Errorf("Fs %q can't rename files (no server-side Move or Copy)", d.Fs()) + err := fmt.Errorf("Fs %q can't rename files (no server-side Move or Copy)", d.Fs()) fs.Errorf(f.Path(), "Dir.Rename error: %v", err) return err } diff --git a/vfs/rc.go b/vfs/rc.go index e6aa4bae4..3450773f0 100644 --- a/vfs/rc.go +++ b/vfs/rc.go @@ -2,12 +2,12 @@ package vfs import ( "context" + "errors" "fmt" "strconv" "strings" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/rc" @@ -44,9 +44,9 @@ func getVFS(in rc.Params) (vfs *VFS, err error) { fsString = cache.Canonicalize(fsString) activeVFS := active[fsString] if len(activeVFS) == 0 { - return nil, errors.Errorf("no VFS found with name %q", fsString) + return nil, fmt.Errorf("no VFS found with name %q", fsString) } else if len(activeVFS) > 1 { - return nil, errors.Errorf("more than one VFS active with name %q", fsString) + return nil, fmt.Errorf("more than one VFS active with name %q", fsString) } delete(in, "fs") // delete the fs parameter return activeVFS[0], nil @@ -111,11 +111,11 @@ func rcRefresh(ctx context.Context, in rc.Params) (out rc.Params, err error) { if v, ok := in[k]; ok { s, ok := v.(string) if !ok { - return out, errors.Errorf("value must be string %q=%v", k, v) + return out, fmt.Errorf("value must be string %q=%v", k, v) } recursive, err = strconv.ParseBool(s) if err != nil { - return out, errors.Errorf("invalid value %q=%v", k, v) + return out, fmt.Errorf("invalid value %q=%v", k, v) } delete(in, k) } @@ -137,7 +137,7 @@ func rcRefresh(ctx context.Context, in rc.Params) (out rc.Params, err error) { for k, v := range in { path, ok := v.(string) if !ok { - return out, errors.Errorf("value must be string %q=%v", k, v) + return out, fmt.Errorf("value must be string %q=%v", k, v) } if strings.HasPrefix(k, "dir") { dir, err := getDir(path) @@ -156,7 +156,7 @@ func rcRefresh(ctx context.Context, in rc.Params) (out rc.Params, err error) { } } } else { - return out, errors.Errorf("unknown key %q", k) + return out, fmt.Errorf("unknown key %q", k) } } } @@ -208,7 +208,7 @@ func rcForget(ctx context.Context, in rc.Params) (out rc.Params, err error) { for k, v := range in { path, ok := v.(string) if !ok { - return out, errors.Errorf("value must be string %q=%v", k, v) + return out, fmt.Errorf("value must be string %q=%v", k, v) } path = strings.Trim(path, "/") if strings.HasPrefix(k, "file") { @@ -216,7 +216,7 @@ func rcForget(ctx context.Context, in rc.Params) (out rc.Params, err error) { } else if strings.HasPrefix(k, "dir") { root.ForgetPath(path, fs.EntryDirectory) } else { - return out, errors.Errorf("unknown key %q", k) + return out, fmt.Errorf("unknown key %q", k) } forgotten = append(forgotten, path) } @@ -230,11 +230,11 @@ func rcForget(ctx context.Context, in rc.Params) (out rc.Params, err error) { func getDuration(k string, v interface{}) (time.Duration, error) { s, ok := v.(string) if !ok { - return 0, errors.Errorf("value must be string %q=%v", k, v) + return 0, fmt.Errorf("value must be string %q=%v", k, v) } interval, err := fs.ParseDuration(s) if err != nil { - return 0, errors.Wrap(err, "parse duration") + return 0, fmt.Errorf("parse duration: %w", err) } return interval, nil } @@ -272,7 +272,7 @@ func getTimeout(in rc.Params) (time.Duration, error) { func getStatus(vfs *VFS, in rc.Params) (out rc.Params, err error) { for k, v := range in { - return nil, errors.Errorf("invalid parameter: %s=%s", k, v) + return nil, fmt.Errorf("invalid parameter: %s=%s", k, v) } return rc.Params{ "enabled": vfs.Opt.PollInterval != 0, @@ -329,7 +329,7 @@ func rcPollInterval(ctx context.Context, in rc.Params) (out rc.Params, err error return nil, err } for k, v := range in { - return nil, errors.Errorf("invalid parameter: %s=%s", k, v) + return nil, fmt.Errorf("invalid parameter: %s=%s", k, v) } if vfs.pollChan == nil { return nil, errors.New("poll-interval is not supported by this remote") diff --git a/vfs/read.go b/vfs/read.go index 1dae5a8d8..a128b0313 100644 --- a/vfs/read.go +++ b/vfs/read.go @@ -2,12 +2,13 @@ package vfs import ( "context" + "errors" + "fmt" "io" "os" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/chunkedreader" @@ -353,7 +354,7 @@ func (fh *ReadFileHandle) checkHash() error { for hashType, dstSum := range fh.hash.Sums() { srcSum, err := o.Hash(context.TODO(), hashType) if err != nil { - if os.IsNotExist(errors.Cause(err)) { + if errors.Is(err, os.ErrNotExist) { // if it was file not found then at // this point we don't care any more continue @@ -361,7 +362,7 @@ func (fh *ReadFileHandle) checkHash() error { return err } if !hash.Equals(dstSum, srcSum) { - return errors.Errorf("corrupted on transfer: %v hash differ %q vs %q", hashType, dstSum, srcSum) + return fmt.Errorf("corrupted on transfer: %v hash differ %q vs %q", hashType, dstSum, srcSum) } } diff --git a/vfs/read_write.go b/vfs/read_write.go index 50697ce3e..a66ea051f 100644 --- a/vfs/read_write.go +++ b/vfs/read_write.go @@ -6,7 +6,6 @@ import ( "os" "sync" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/log" "github.com/rclone/rclone/vfs/vfscache" @@ -54,7 +53,7 @@ func newRWFileHandle(d *Dir, f *File, flags int) (fh *RWFileHandle, err error) { if !fh.readOnly() && (fh.flags&os.O_TRUNC != 0 || (fh.flags&os.O_CREATE != 0 && !exists)) { err = fh.Truncate(0) if err != nil { - return nil, errors.Wrap(err, "cache open with O_TRUNC: failed to truncate") + return nil, fmt.Errorf("cache open with O_TRUNC: failed to truncate: %w", err) } // we definitely need to write back the item even if we don't write to it item.Dirty() @@ -92,7 +91,7 @@ func (fh *RWFileHandle) openPending() (err error) { o := fh.file.getObject() err = fh.item.Open(o) if err != nil { - return errors.Wrap(err, "open RW handle failed to open cache file") + return fmt.Errorf("open RW handle failed to open cache file: %w", err) } size := fh._size() // update size in file and read size diff --git a/vfs/read_write_test.go b/vfs/read_write_test.go index f7335087c..1f5211472 100644 --- a/vfs/read_write_test.go +++ b/vfs/read_write_test.go @@ -2,6 +2,7 @@ package vfs import ( "context" + "errors" "fmt" "io" "io/ioutil" @@ -9,7 +10,6 @@ import ( "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fstest" @@ -398,7 +398,7 @@ func TestRWFileHandleWriteNoWrite(t *testing.T) { // Close the file without writing to it err := fh.Close() - if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles { + if errors.Is(err, fs.ErrorCantUploadEmptyFiles) { t.Logf("skipping test: %v", err) return } diff --git a/vfs/vfs_test.go b/vfs/vfs_test.go index 4ece14c4f..893eeecbe 100644 --- a/vfs/vfs_test.go +++ b/vfs/vfs_test.go @@ -4,13 +4,13 @@ package vfs import ( "context" + "errors" "fmt" "io" "os" "testing" "time" - "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/all" // import all the backends "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fstest" @@ -283,7 +283,7 @@ func TestVFSOpenFile(t *testing.T) { require.NoError(t, err) assert.NotNil(t, fd) err = fd.Close() - if errors.Cause(err) != fs.ErrorCantUploadEmptyFiles { + if !errors.Is(err, fs.ErrorCantUploadEmptyFiles) { require.NoError(t, err) } diff --git a/vfs/vfscache/cache.go b/vfs/vfscache/cache.go index 483bdf39c..88d1f2f24 100644 --- a/vfs/vfscache/cache.go +++ b/vfs/vfscache/cache.go @@ -3,6 +3,7 @@ package vfscache import ( "context" + "errors" "fmt" "os" "path" @@ -14,7 +15,6 @@ import ( "time" sysdnotify "github.com/iguanesolutions/go-systemd/v5/notify" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" fscache "github.com/rclone/rclone/fs/cache" "github.com/rclone/rclone/fs/config" @@ -130,7 +130,7 @@ func New(ctx context.Context, fremote fs.Fs, opt *vfscommon.Options, avFn AddVir // load in the cache and metadata off disk err = c.reload(ctx) if err != nil { - return nil, errors.Wrap(err, "failed to load cache") + return nil, fmt.Errorf("failed to load cache: %w", err) } // Remove any empty directories @@ -160,9 +160,9 @@ func createRootDir(parentOSPath string, name string, relativeDirOSPath string) ( // createRootDirs creates all cache root directories func createRootDirs(parentOSPath string, relativeDirOSPath string) (dataOSPath string, metaOSPath string, err error) { if dataOSPath, err = createRootDir(parentOSPath, "vfs", relativeDirOSPath); err != nil { - err = errors.Wrap(err, "failed to create data cache directory") + err = fmt.Errorf("failed to create data cache directory: %w", err) } else if metaOSPath, err = createRootDir(parentOSPath, "vfsMeta", relativeDirOSPath); err != nil { - err = errors.Wrap(err, "failed to create metadata cache directory") + err = fmt.Errorf("failed to create metadata cache directory: %w", err) } return } @@ -176,12 +176,12 @@ func (c *Cache) createItemDir(name string) (string, error) { parentPath := c.toOSPath(parent) err := createDir(parentPath) if err != nil { - return "", errors.Wrap(err, "failed to create data cache item directory") + return "", fmt.Errorf("failed to create data cache item directory: %w", err) } parentPathMeta := c.toOSPathMeta(parent) err = createDir(parentPathMeta) if err != nil { - return "", errors.Wrap(err, "failed to create metadata cache item directory") + return "", fmt.Errorf("failed to create metadata cache item directory: %w", err) } return filepath.Join(parentPath, leaf), nil } @@ -195,9 +195,9 @@ func getBackend(ctx context.Context, parentPath string, name string, relativeDir // getBackends gets backends for all cache root dirs func getBackends(ctx context.Context, parentPath string, relativeDirPath string) (fdata fs.Fs, fmeta fs.Fs, err error) { if fdata, err = getBackend(ctx, parentPath, "vfs", relativeDirPath); err != nil { - err = errors.Wrap(err, "failed to get data cache backend") + err = fmt.Errorf("failed to get data cache backend: %w", err) } else if fmeta, err = getBackend(ctx, parentPath, "vfsMeta", relativeDirPath); err != nil { - err = errors.Wrap(err, "failed to get metadata cache backend") + err = fmt.Errorf("failed to get metadata cache backend: %w", err) } return } @@ -342,32 +342,32 @@ func rename(osOldPath, osNewPath string) error { if os.IsNotExist(err) { return nil } - return errors.Wrapf(err, "Failed to stat source: %s", osOldPath) + return fmt.Errorf("Failed to stat source: %s: %w", osOldPath, err) } if !sfi.Mode().IsRegular() { // cannot copy non-regular files (e.g., directories, symlinks, devices, etc.) - return errors.Errorf("Non-regular source file: %s (%q)", sfi.Name(), sfi.Mode().String()) + return fmt.Errorf("Non-regular source file: %s (%q)", sfi.Name(), sfi.Mode().String()) } dfi, err := os.Stat(osNewPath) if err != nil { if !os.IsNotExist(err) { - return errors.Wrapf(err, "Failed to stat destination: %s", osNewPath) + return fmt.Errorf("Failed to stat destination: %s: %w", osNewPath, err) } parent := vfscommon.OsFindParent(osNewPath) err = createDir(parent) if err != nil { - return errors.Wrapf(err, "Failed to create parent dir: %s", parent) + return fmt.Errorf("Failed to create parent dir: %s: %w", parent, err) } } else { if !(dfi.Mode().IsRegular()) { - return errors.Errorf("Non-regular destination file: %s (%q)", dfi.Name(), dfi.Mode().String()) + return fmt.Errorf("Non-regular destination file: %s (%q)", dfi.Name(), dfi.Mode().String()) } if os.SameFile(sfi, dfi) { return nil } } if err = os.Rename(osOldPath, osNewPath); err != nil { - return errors.Wrapf(err, "Failed to rename in cache: %s to %s", osOldPath, osNewPath) + return fmt.Errorf("Failed to rename in cache: %s to %s: %w", osOldPath, osNewPath, err) } return nil } @@ -478,7 +478,7 @@ func (c *Cache) walk(dir string, fn func(osPath string, fi os.FileInfo, name str // Find path relative to the cache root name, err := filepath.Rel(dir, osPath) if err != nil { - return errors.Wrap(err, "filepath.Rel failed in walk") + return fmt.Errorf("filepath.Rel failed in walk: %w", err) } if name == "." { name = "" @@ -511,7 +511,7 @@ func (c *Cache) reload(ctx context.Context) error { return nil }) if err != nil { - return errors.Wrapf(err, "failed to walk cache %q", dir) + return fmt.Errorf("failed to walk cache %q: %w", dir, err) } } return nil diff --git a/vfs/vfscache/downloaders/downloaders.go b/vfs/vfscache/downloaders/downloaders.go index 94c4133d8..c6d769a4f 100644 --- a/vfs/vfscache/downloaders/downloaders.go +++ b/vfs/vfscache/downloaders/downloaders.go @@ -2,10 +2,11 @@ package downloaders import ( "context" + "errors" + "fmt" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/asyncreader" @@ -182,7 +183,7 @@ func (dls *Downloaders) _newDownloader(r ranges.Range) (dl *downloader, err erro err = dl.open(dl.offset) if err != nil { _ = dl.close(err) - return nil, errors.Wrap(err, "failed to open downloader") + return nil, fmt.Errorf("failed to open downloader: %w", err) } dls.dls = append(dls.dls, dl) @@ -361,7 +362,7 @@ func (dls *Downloaders) _ensureDownloader(r ranges.Range) (err error) { dl, err = dls._newDownloader(r) if err != nil { dls._countErrors(0, err) - return errors.Wrap(err, "failed to start downloader") + return fmt.Errorf("failed to start downloader: %w", err) } return err } @@ -534,7 +535,7 @@ func (dl *downloader) open(offset int64) (err error) { in0 := chunkedreader.New(context.TODO(), dl.dls.src, int64(dl.dls.opt.ChunkSize), int64(dl.dls.opt.ChunkSizeLimit)) _, err = in0.Seek(offset, 0) if err != nil { - return errors.Wrap(err, "vfs reader: failed to open source file") + return fmt.Errorf("vfs reader: failed to open source file: %w", err) } dl.in = dl.tr.Account(dl.dls.ctx, in0).WithBuffer() // account and buffer the transfer @@ -550,7 +551,7 @@ func (dl *downloader) open(offset int64) (err error) { func (dl *downloader) close(inErr error) (err error) { // defer log.Trace(dl.dls.src, "inErr=%v", err)("err=%v", &err) checkErr := func(e error) { - if e == nil || errors.Cause(err) == asyncreader.ErrorStreamAbandoned { + if e == nil || errors.Is(err, asyncreader.ErrorStreamAbandoned) { return } err = e @@ -617,8 +618,8 @@ func (dl *downloader) stopAndClose(inErr error) (err error) { func (dl *downloader) download() (n int64, err error) { // defer log.Trace(dl.dls.src, "")("err=%v", &err) n, err = dl.in.WriteTo(dl) - if err != nil && errors.Cause(err) != asyncreader.ErrorStreamAbandoned { - return n, errors.Wrap(err, "vfs reader: failed to write to cache file") + if err != nil && !errors.Is(err, asyncreader.ErrorStreamAbandoned) { + return n, fmt.Errorf("vfs reader: failed to write to cache file: %w", err) } return n, nil diff --git a/vfs/vfscache/item.go b/vfs/vfscache/item.go index b8974ff71..6e06bcd51 100644 --- a/vfs/vfscache/item.go +++ b/vfs/vfscache/item.go @@ -3,13 +3,13 @@ package vfscache import ( "context" "encoding/json" + "errors" "fmt" "io" "os" "sync" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/operations" @@ -199,13 +199,13 @@ func (item *Item) load() (exists bool, err error) { if os.IsNotExist(err) { return false, err } - return true, errors.Wrap(err, "vfs cache item: failed to read metadata") + return true, fmt.Errorf("vfs cache item: failed to read metadata: %w", err) } defer fs.CheckClose(in, &err) decoder := json.NewDecoder(in) err = decoder.Decode(&item.info) if err != nil { - return true, errors.Wrap(err, "vfs cache item: corrupt metadata") + return true, fmt.Errorf("vfs cache item: corrupt metadata: %w", err) } return true, nil } @@ -217,14 +217,14 @@ func (item *Item) _save() (err error) { osPathMeta := item.c.toOSPathMeta(item.name) // No locking in Cache out, err := os.Create(osPathMeta) if err != nil { - return errors.Wrap(err, "vfs cache item: failed to write metadata") + return fmt.Errorf("vfs cache item: failed to write metadata: %w", err) } defer fs.CheckClose(out, &err) encoder := json.NewEncoder(out) encoder.SetIndent("", "\t") err = encoder.Encode(item.info) if err != nil { - return errors.Wrap(err, "vfs cache item: failed to encode metadata") + return fmt.Errorf("vfs cache item: failed to encode metadata: %w", err) } return nil } @@ -261,7 +261,7 @@ func (item *Item) _truncate(size int64) (err error) { fd, err = file.OpenFile(osPath, os.O_CREATE|os.O_WRONLY, 0600) } if err != nil { - return errors.Wrap(err, "vfs cache: truncate: failed to open cache file") + return fmt.Errorf("vfs cache: truncate: failed to open cache file: %w", err) } defer fs.CheckClose(fd, &err) @@ -276,7 +276,7 @@ func (item *Item) _truncate(size int64) (err error) { err = fd.Truncate(size) if err != nil { - return errors.Wrap(err, "vfs cache: truncate") + return fmt.Errorf("vfs cache: truncate: %w", err) } item.info.Size = size @@ -291,8 +291,8 @@ func (item *Item) _truncate(size int64) (err error) { // call with the lock held func (item *Item) _truncateToCurrentSize() (err error) { size, err := item._getSize() - if err != nil && !os.IsNotExist(errors.Cause(err)) { - return errors.Wrap(err, "truncate to current size") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("truncate to current size: %w", err) } if size < 0 { // FIXME ignore unknown length files @@ -326,8 +326,8 @@ func (item *Item) Truncate(size int64) (err error) { // Read old size oldSize, err := item._getSize() if err != nil { - if !os.IsNotExist(errors.Cause(err)) { - return errors.Wrap(err, "truncate failed to read size") + if !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("truncate failed to read size: %w", err) } oldSize = 0 } @@ -462,7 +462,7 @@ func (item *Item) _createFile(osPath string) (err error) { item.modified = false fd, err := file.OpenFile(osPath, os.O_RDWR, 0600) if err != nil { - return errors.Wrap(err, "vfs cache item: open failed") + return fmt.Errorf("vfs cache item: open failed: %w", err) } err = file.SetSparse(fd) if err != nil { @@ -477,7 +477,7 @@ func (item *Item) _createFile(osPath string) (err error) { fs.Errorf(item.name, "vfs cache: item.fd.Close: closeErr: %v", err) } item.fd = nil - return errors.Wrap(err, "vfs cache item: _save failed") + return fmt.Errorf("vfs cache item: _save failed: %w", err) } return err } @@ -513,12 +513,12 @@ func (item *Item) open(o fs.Object) (err error) { osPath, err := item.c.createItemDir(item.name) // No locking in Cache if err != nil { - return errors.Wrap(err, "vfs cache item: createItemDir failed") + return fmt.Errorf("vfs cache item: createItemDir failed: %w", err) } err = item._checkObject(o) if err != nil { - return errors.Wrap(err, "vfs cache item: check object failed") + return fmt.Errorf("vfs cache item: check object failed: %w", err) } item.opens++ @@ -531,7 +531,7 @@ func (item *Item) open(o fs.Object) (err error) { item._remove("item.open failed on _createFile, remove cache data/metadata files") item.fd = nil item.opens-- - return errors.Wrap(err, "vfs cache item: create cache file failed") + return fmt.Errorf("vfs cache item: create cache file failed: %w", err) } // Unlock the Item.mu so we can call some methods which take Cache.mu item.mu.Unlock() @@ -548,7 +548,7 @@ func (item *Item) open(o fs.Object) (err error) { if oldItem.opens != 0 { // Put the item back and return an error item.c.put(item.name, oldItem) // LOCKING in Cache method - err = errors.Errorf("internal error: item %q already open in the cache", item.name) + err = fmt.Errorf("internal error: item %q already open in the cache", item.name) } oldItem.mu.Unlock() } @@ -574,7 +574,7 @@ func (item *Item) _store(ctx context.Context, storeFn StoreFn) (err error) { // Transfer the temp file to the remote cacheObj, err := item.c.fcache.NewObject(ctx, item.name) if err != nil && err != fs.ErrorObjectNotFound { - return errors.Wrap(err, "vfs cache: failed to find cache file") + return fmt.Errorf("vfs cache: failed to find cache file: %w", err) } // Object has disappeared if cacheObj == nil @@ -584,7 +584,7 @@ func (item *Item) _store(ctx context.Context, storeFn StoreFn) (err error) { o, err := operations.Copy(ctx, item.c.fremote, o, name, cacheObj) item.mu.Lock() if err != nil { - return errors.Wrap(err, "vfs cache: failed to transfer file from cache to remote") + return fmt.Errorf("vfs cache: failed to transfer file from cache to remote: %w", err) } item.o = o item._updateFingerprint() @@ -648,7 +648,7 @@ func (item *Item) Close(storeFn StoreFn) (err error) { if item.info.Dirty && item.o != nil { err = item._ensure(0, item.info.Size) if err != nil { - return errors.Wrap(err, "vfs cache: failed to download missing parts of cache file") + return fmt.Errorf("vfs cache: failed to download missing parts of cache file: %w", err) } } @@ -751,11 +751,11 @@ func (item *Item) reload(ctx context.Context) error { // put the file into the directory listings size, err := item._getSize() if err != nil { - return errors.Wrap(err, "reload: failed to read size") + return fmt.Errorf("reload: failed to read size: %w", err) } err = item.c.AddVirtual(item.name, size, false) if err != nil { - return errors.Wrap(err, "reload: failed to add virtual dir entry") + return fmt.Errorf("reload: failed to add virtual dir entry: %w", err) } return nil } @@ -807,7 +807,7 @@ func (item *Item) _checkObject(o fs.Object) error { err := item._truncateToCurrentSize() if err != nil { - return errors.Wrap(err, "vfs cache item: open truncate failed") + return fmt.Errorf("vfs cache item: open truncate failed: %w", err) } return nil @@ -1265,7 +1265,7 @@ func (item *Item) WriteAt(b []byte, off int64) (n int, err error) { // Do the writing with Item.mu unlocked n, err = item.fd.WriteAt(b, off) if err == nil && n != len(b) { - err = errors.Errorf("short write: tried to write %d but only %d written", len(b), n) + err = fmt.Errorf("short write: tried to write %d but only %d written", len(b), n) } item.mu.Lock() item._written(off, int64(n)) @@ -1327,7 +1327,7 @@ func (item *Item) WriteAtNoOverwrite(b []byte, off int64) (n int, skipped int, e // fs.Debugf(item.name, "write chunk offset=%d size=%d", off, size) nn, err = item.fd.WriteAt(b[:size], off) if err == nil && nn != size { - err = errors.Errorf("downloader: short write: tried to write %d but only %d written", size, nn) + err = fmt.Errorf("downloader: short write: tried to write %d but only %d written", size, nn) } item._written(off, int64(nn)) } @@ -1356,11 +1356,11 @@ func (item *Item) Sync() (err error) { // sync the file and the metadata to disk err = item.fd.Sync() if err != nil { - return errors.Wrap(err, "vfs cache item sync: failed to sync file") + return fmt.Errorf("vfs cache item sync: failed to sync file: %w", err) } err = item._save() if err != nil { - return errors.Wrap(err, "vfs cache item sync: failed to sync metadata") + return fmt.Errorf("vfs cache item sync: failed to sync metadata: %w", err) } return nil } diff --git a/vfs/vfscache/writeback/writeback.go b/vfs/vfscache/writeback/writeback.go index 5db10c603..5f63f5461 100644 --- a/vfs/vfscache/writeback/writeback.go +++ b/vfs/vfscache/writeback/writeback.go @@ -5,12 +5,12 @@ package writeback import ( "container/heap" "context" + "errors" "sync" "sync/atomic" "time" "github.com/rclone/rclone/fs" - "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/vfs/vfscommon" ) @@ -365,7 +365,7 @@ func (wb *WriteBack) upload(ctx context.Context, wbItem *writeBackItem) { if wbItem.delay > maxUploadDelay { wbItem.delay = maxUploadDelay } - if _, uerr := fserrors.Cause(err); uerr == context.Canceled { + if errors.Is(err, context.Canceled) { fs.Infof(wbItem.name, "vfs cache: upload canceled") // Upload was cancelled so reset timer wbItem.delay = wb.opt.WriteBack diff --git a/vfs/vfscache/writeback/writeback_test.go b/vfs/vfscache/writeback/writeback_test.go index 6b0398b50..512d0eeb7 100644 --- a/vfs/vfscache/writeback/writeback_test.go +++ b/vfs/vfscache/writeback/writeback_test.go @@ -3,13 +3,13 @@ package writeback import ( "container/heap" "context" + "errors" "fmt" "strings" "sync" "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/vfs/vfscommon" "github.com/stretchr/testify/assert" diff --git a/vfs/vfscommon/cachemode.go b/vfs/vfscommon/cachemode.go index 38b6fec99..a7f35fe9c 100644 --- a/vfs/vfscommon/cachemode.go +++ b/vfs/vfscommon/cachemode.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/rclone/rclone/fs" - "github.com/rclone/rclone/lib/errors" ) // CacheMode controls the functionality of the cache @@ -41,7 +40,7 @@ func (l *CacheMode) Set(s string) error { return nil } } - return errors.Errorf("Unknown cache mode level %q", s) + return fmt.Errorf("Unknown cache mode level %q", s) } // Type of the value @@ -53,7 +52,7 @@ func (l *CacheMode) Type() string { func (l *CacheMode) UnmarshalJSON(in []byte) error { return fs.UnmarshalJSONFlag(in, l, func(i int64) error { if i < 0 || i >= int64(len(cacheModeToString)) { - return errors.Errorf("Unknown cache mode level %d", i) + return fmt.Errorf("Unknown cache mode level %d", i) } *l = CacheMode(i) return nil diff --git a/vfs/vfsflags/filemode.go b/vfs/vfsflags/filemode.go index 7d8eb028b..50a8bc423 100644 --- a/vfs/vfsflags/filemode.go +++ b/vfs/vfsflags/filemode.go @@ -4,8 +4,6 @@ import ( "fmt" "os" "strconv" - - "github.com/pkg/errors" ) // FileMode is a command line friendly os.FileMode @@ -22,7 +20,7 @@ func (x *FileMode) String() string { func (x *FileMode) Set(s string) error { i, err := strconv.ParseInt(s, 8, 64) if err != nil { - return errors.Wrap(err, "Bad FileMode - must be octal digits") + return fmt.Errorf("Bad FileMode - must be octal digits: %w", err) } *x.Mode = (os.FileMode)(i) return nil diff --git a/vfs/write_test.go b/vfs/write_test.go index 431ae084e..99f5d63b2 100644 --- a/vfs/write_test.go +++ b/vfs/write_test.go @@ -2,13 +2,13 @@ package vfs import ( "context" + "errors" "io" "os" "sync" "testing" "time" - "github.com/pkg/errors" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fstest" "github.com/rclone/rclone/lib/random" @@ -117,7 +117,7 @@ func TestWriteFileHandleMethods(t *testing.T) { h, err = vfs.OpenFile("file1", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) require.NoError(t, err) err = h.Close() - if errors.Cause(err) != fs.ErrorCantUploadEmptyFiles { + if !errors.Is(err, fs.ErrorCantUploadEmptyFiles) { assert.NoError(t, err) checkListing(t, root, []string{"file1,0,false"}) } @@ -215,7 +215,7 @@ func TestWriteFileHandleRelease(t *testing.T) { // Check Release closes file err := fh.Release() - if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles { + if errors.Is(err, fs.ErrorCantUploadEmptyFiles) { t.Logf("skipping test: %v", err) return } @@ -298,7 +298,7 @@ func testFileReadAt(t *testing.T, n int) { // Close the file without writing to it if n==0 err := fh.Close() - if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles { + if errors.Is(err, fs.ErrorCantUploadEmptyFiles) { t.Logf("skipping test: %v", err) return }