From 334eee0c8cef4b7b37b31c06b31f91c7e727188b Mon Sep 17 00:00:00 2001 From: Matt Hook Date: Fri, 5 May 2023 12:19:47 +1200 Subject: [PATCH] fix(errors): wrap db errors, improve error handling (#8859) * use error check func, wrap db object not found * add errorlint and fix all the linting errors * add exportloopref linter and fix errors * fix incorrect error details returned on an api * fix new errors * increase linter timeout * increase timeout to 10minutes * increase timeout to 10minutes * rebase and fix new lint errors * make CE match EE * fix govet issue --- .github/workflows/lint.yml | 9 +++---- api/.golangci.yaml | 27 ++++++++++--------- api/archive/targz.go | 5 ++-- api/database/boltdb/db.go | 19 +++++++++++-- api/database/boltdb/tx.go | 4 +-- api/database/boltdb/tx_test.go | 4 +-- .../apikeyrepository/apikeyrepository.go | 7 ++--- api/dataservices/errors/errors.go | 5 ++-- api/dataservices/interface.go | 10 +++---- .../resourcecontrol/resourcecontrol.go | 3 ++- api/dataservices/resourcecontrol/tx.go | 3 ++- api/dataservices/stack/stack.go | 13 ++++----- api/dataservices/stack/tests/stack_test.go | 2 +- api/dataservices/team/team.go | 7 ++--- api/dataservices/user/user.go | 7 ++--- api/dataservices/webhook/webhook.go | 11 ++++---- api/datastore/backup.go | 4 +-- api/datastore/datastore.go | 3 ++- api/datastore/migrate_data_test.go | 2 +- api/datastore/migrator/migrate_dbversion26.go | 4 +-- api/datastore/migrator/migrate_dbversion31.go | 4 +-- api/datastore/migrator/migrate_dbversion71.go | 4 +-- api/datastore/migrator/migrate_dbversion90.go | 4 +-- api/docker/snapshot.go | 1 + api/git/backup.go | 2 +- api/http/handler/edgegroups/handler.go | 6 +++-- api/http/handler/edgejobs/edgejob_delete.go | 6 +++-- .../edgejobs/edgejob_tasklogs_clear.go | 6 +++-- .../edgejobs/edgejob_tasklogs_collect.go | 6 +++-- api/http/handler/edgejobs/handler.go | 6 +++-- .../endpoints/endpoint_registries_list.go | 4 +-- .../handler/gitops/git_repo_file_preview.go | 8 +++--- .../hostmanagement/openamt/amtactivation.go | 3 +-- .../hostmanagement/openamt/amtdevices.go | 3 +-- .../handler/hostmanagement/openamt/amtrpc.go | 3 +-- api/http/handler/kubernetes/handler.go | 3 +-- api/http/handler/kubernetes/ingresses.go | 3 +-- api/http/handler/stacks/webhook_invoke.go | 4 ++- api/http/handler/tags/handler.go | 6 +++-- api/http/handler/tags/tag_delete.go | 6 +++-- .../handler/users/user_remove_access_token.go | 3 ++- api/http/handler/websocket/hijack.go | 3 ++- api/http/middlewares/withitem.go | 4 +-- api/http/proxy/factory/docker/registry.go | 1 + api/http/proxy/factory/docker/transport.go | 3 +-- api/internal/edge/edgestack.go | 1 + api/internal/edge/edgestacks/service.go | 2 +- api/kubernetes/cli/exec.go | 6 +++-- api/kubernetes/cli/pod_test.go | 5 ++-- api/scheduler/scheduler.go | 2 +- api/stacks/stackutils/gitops.go | 2 +- golangci-lint.sh | 4 +-- 52 files changed, 158 insertions(+), 115 deletions(-) mode change 100644 => 100755 golangci-lint.sh diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e032f3088..b9604eafb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,13 +21,12 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: '14' + node-version: '18' cache: 'yarn' - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: - go-version: 1.19.4 + go-version: 1.19.5 - run: yarn --frozen-lockfile - - name: Run linters uses: wearerequired/lint-action@v1 with: @@ -44,4 +43,4 @@ jobs: with: version: latest working-directory: api - args: -c .golangci.yaml + args: --timeout=10m -c .golangci.yaml diff --git a/api/.golangci.yaml b/api/.golangci.yaml index f6f418b8e..6b117490b 100644 --- a/api/.golangci.yaml +++ b/api/.golangci.yaml @@ -1,8 +1,13 @@ linters: - # Disable all linters. + # Disable all linters, the defaults don't pass on our code yet disable-all: true + + # Enable these for now enable: - depguard + - govet + - errorlint + - exportloopref linters-settings: depguard: list-type: denylist @@ -13,14 +18,12 @@ linters-settings: packages-with-error-message: - github.com/sirupsen/logrus: 'logging is allowed only by github.com/rs/zerolog' ignore-file-rules: - - "**/*_test.go" - # Create additional guards that follow the same configuration pattern. - # Results from all guards are aggregated together. - # additional-guards: - # - list-type: allowlist - # include-go-root: false - # packages: - # - github.com/sirupsen/logrus - # # Specify rules by which the linter ignores certain files for consideration. - # ignore-file-rules: - # - "!**/*_test.go" \ No newline at end of file + - '**/*_test.go' + +# errorlint is causing a typecheck error for some reason. The go compiler will report these +# anyway, so ignore them from the linter +issues: + exclude-rules: + - path: ./ + linters: + - typecheck diff --git a/api/archive/targz.go b/api/archive/targz.go index 757854a23..301ff829f 100644 --- a/api/archive/targz.go +++ b/api/archive/targz.go @@ -3,6 +3,7 @@ package archive import ( "archive/tar" "compress/gzip" + "errors" "fmt" "io" "os" @@ -84,7 +85,7 @@ func ExtractTarGz(r io.Reader, outputDirPath string) error { for { header, err := tarReader.Next() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } @@ -109,7 +110,7 @@ func ExtractTarGz(r io.Reader, outputDirPath string) error { } outFile.Close() default: - return fmt.Errorf("Tar: uknown type: %v in %s", + return fmt.Errorf("tar: unknown type: %v in %s", header.Typeflag, header.Name) } diff --git a/api/database/boltdb/db.go b/api/database/boltdb/db.go index 3f27d09fe..52b7cbea4 100644 --- a/api/database/boltdb/db.go +++ b/api/database/boltdb/db.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "math" "os" "path" "time" @@ -182,7 +183,7 @@ func (connection *DbConnection) BackupTo(w io.Writer) error { func (connection *DbConnection) ExportRaw(filename string) error { databasePath := connection.GetDatabaseFilePath() if _, err := os.Stat(databasePath); err != nil { - return fmt.Errorf("stat on %s failed: %s", databasePath, err) + return fmt.Errorf("stat on %s failed, error: %w", databasePath, err) } b, err := connection.ExportJSON(databasePath, true) @@ -201,6 +202,20 @@ func (connection *DbConnection) ConvertToKey(v int) []byte { return b } +// keyToString Converts a key to a string value suitable for logging +func keyToString(b []byte) string { + if len(b) != 8 { + return string(b) + } + + v := binary.BigEndian.Uint64(b) + if v <= math.MaxInt32 { + return fmt.Sprintf("%d", v) + } + + return string(b) +} + // CreateBucket is a generic function used to create a bucket inside a database. func (connection *DbConnection) SetServiceName(bucketName string) error { return connection.UpdateTx(func(tx portainer.Transaction) error { @@ -237,7 +252,7 @@ func (connection *DbConnection) UpdateObjectFunc(bucketName string, key []byte, data := bucket.Get(key) if data == nil { - return dserrors.ErrObjectNotFound + return fmt.Errorf("%w (bucket=%s, key=%s)", dserrors.ErrObjectNotFound, bucketName, keyToString(key)) } err := connection.UnmarshalObjectWithJsoniter(data, object) diff --git a/api/database/boltdb/tx.go b/api/database/boltdb/tx.go index c4503fde8..b27add6b9 100644 --- a/api/database/boltdb/tx.go +++ b/api/database/boltdb/tx.go @@ -2,6 +2,7 @@ package boltdb import ( "bytes" + "fmt" dserrors "github.com/portainer/portainer/api/dataservices/errors" @@ -24,7 +25,7 @@ func (tx *DbTransaction) GetObject(bucketName string, key []byte, object interfa value := bucket.Get(key) if value == nil { - return dserrors.ErrObjectNotFound + return fmt.Errorf("%w (bucket=%s, key=%s)", dserrors.ErrObjectNotFound, bucketName, keyToString(key)) } data := make([]byte, len(value)) @@ -74,7 +75,6 @@ func (tx *DbTransaction) GetNextIdentifier(bucketName string) int { id, err := bucket.NextSequence() if err != nil { log.Error().Err(err).Str("bucket", bucketName).Msg("failed to get the next identifer") - return 0 } diff --git a/api/database/boltdb/tx_test.go b/api/database/boltdb/tx_test.go index b2def3303..e7dab7319 100644 --- a/api/database/boltdb/tx_test.go +++ b/api/database/boltdb/tx_test.go @@ -5,7 +5,7 @@ import ( "testing" portainer "github.com/portainer/portainer/api" - dserrors "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" ) const testBucketName = "test-bucket" @@ -97,7 +97,7 @@ func TestTxs(t *testing.T) { err = conn.ViewTx(func(tx portainer.Transaction) error { return tx.GetObject(testBucketName, conn.ConvertToKey(testId), &obj) }) - if err != dserrors.ErrObjectNotFound { + if !dataservices.IsErrObjectNotFound(err) { t.Fatal(err) } diff --git a/api/dataservices/apikeyrepository/apikeyrepository.go b/api/dataservices/apikeyrepository/apikeyrepository.go index 561bde620..00557e3a7 100644 --- a/api/dataservices/apikeyrepository/apikeyrepository.go +++ b/api/dataservices/apikeyrepository/apikeyrepository.go @@ -2,10 +2,11 @@ package apikeyrepository import ( "bytes" + "errors" "fmt" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + dserrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -78,12 +79,12 @@ func (service *Service) GetAPIKeyByDigest(digest []byte) (*portainer.APIKey, err return &portainer.APIKey{}, nil }) - if err == stop { + if errors.Is(err, stop) { return k, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err diff --git a/api/dataservices/errors/errors.go b/api/dataservices/errors/errors.go index 75355908a..5c4548e37 100644 --- a/api/dataservices/errors/errors.go +++ b/api/dataservices/errors/errors.go @@ -1,9 +1,10 @@ package errors -import "errors" +import ( + "errors" +) var ( - // TODO: i'm pretty sure this needs wrapping at several levels ErrObjectNotFound = errors.New("object not found inside the database") ErrWrongDBEdition = errors.New("the Portainer database is set for Portainer Business Edition, please follow the instructions in our documentation to downgrade it: https://documentation.portainer.io/v2.0-be/downgrade/be-to-ce/") ErrDBImportFailed = errors.New("importing backup failed") diff --git a/api/dataservices/interface.go b/api/dataservices/interface.go index 0cc829f2e..02334c6de 100644 --- a/api/dataservices/interface.go +++ b/api/dataservices/interface.go @@ -1,15 +1,13 @@ package dataservices -// "github.com/portainer/portainer/api/dataservices" - import ( + "errors" "io" "time" - "github.com/portainer/portainer/api/database/models" - "github.com/portainer/portainer/api/dataservices/errors" - portainer "github.com/portainer/portainer/api" + "github.com/portainer/portainer/api/database/models" + dserrors "github.com/portainer/portainer/api/dataservices/errors" ) type ( @@ -325,5 +323,5 @@ type ( ) func IsErrObjectNotFound(e error) bool { - return e == errors.ErrObjectNotFound + return errors.Is(e, dserrors.ErrObjectNotFound) } diff --git a/api/dataservices/resourcecontrol/resourcecontrol.go b/api/dataservices/resourcecontrol/resourcecontrol.go index 208f9456e..624f078ec 100644 --- a/api/dataservices/resourcecontrol/resourcecontrol.go +++ b/api/dataservices/resourcecontrol/resourcecontrol.go @@ -1,6 +1,7 @@ package resourcecontrol import ( + "errors" "fmt" portainer "github.com/portainer/portainer/api" @@ -82,7 +83,7 @@ func (service *Service) ResourceControlByResourceIDAndType(resourceID string, re return &portainer.ResourceControl{}, nil }) - if err == stop { + if errors.Is(err, stop) { return resourceControl, nil } diff --git a/api/dataservices/resourcecontrol/tx.go b/api/dataservices/resourcecontrol/tx.go index 485fabcda..b18736571 100644 --- a/api/dataservices/resourcecontrol/tx.go +++ b/api/dataservices/resourcecontrol/tx.go @@ -1,6 +1,7 @@ package resourcecontrol import ( + "errors" "fmt" portainer "github.com/portainer/portainer/api" @@ -60,7 +61,7 @@ func (service ServiceTx) ResourceControlByResourceIDAndType(resourceID string, r return &portainer.ResourceControl{}, nil }) - if err == stop { + if errors.Is(err, stop) { return resourceControl, nil } diff --git a/api/dataservices/stack/stack.go b/api/dataservices/stack/stack.go index 6e697930a..b979ded3f 100644 --- a/api/dataservices/stack/stack.go +++ b/api/dataservices/stack/stack.go @@ -1,11 +1,12 @@ package stack import ( + "errors" "fmt" "strings" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + dserrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -71,11 +72,11 @@ func (service *Service) StackByName(name string) (*portainer.Stack, error) { return &portainer.Stack{}, nil }) - if err == stop { + if errors.Is(err, stop) { return s, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err @@ -92,7 +93,7 @@ func (service *Service) StacksByName(name string) ([]portainer.Stack, error) { stack, ok := obj.(portainer.Stack) if !ok { log.Debug().Str("obj", fmt.Sprintf("%#v", obj)).Msg("failed to convert to Stack object") - return nil, fmt.Errorf("Failed to convert to Stack object: %s", obj) + return nil, fmt.Errorf("failed to convert to Stack object: %s", obj) } if stack.Name == name { @@ -173,11 +174,11 @@ func (service *Service) StackByWebhookID(id string) (*portainer.Stack, error) { return &portainer.Stack{}, nil }) - if err == stop { + if errors.Is(err, stop) { return s, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err diff --git a/api/dataservices/stack/tests/stack_test.go b/api/dataservices/stack/tests/stack_test.go index 4c15479f7..08106e625 100644 --- a/api/dataservices/stack/tests/stack_test.go +++ b/api/dataservices/stack/tests/stack_test.go @@ -59,7 +59,7 @@ func (b *stackBuilder) createNewStack(webhookID string) portainer.Stack { Type: portainer.DockerComposeStack, EndpointID: 2, EntryPoint: filesystem.ComposeFileDefaultName, - Env: []portainer.Pair{{"Name1", "Value1"}}, + Env: []portainer.Pair{{Name: "Name1", Value: "Value1"}}, Status: portainer.StackStatusActive, CreationDate: time.Now().Unix(), ProjectPath: "/tmp/project", diff --git a/api/dataservices/team/team.go b/api/dataservices/team/team.go index 05b20dd8d..d53fa6ccb 100644 --- a/api/dataservices/team/team.go +++ b/api/dataservices/team/team.go @@ -1,11 +1,12 @@ package team import ( + "errors" "fmt" "strings" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + dserrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -71,11 +72,11 @@ func (service *Service) TeamByName(name string) (*portainer.Team, error) { return &portainer.Team{}, nil }) - if err == stop { + if errors.Is(err, stop) { return t, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err diff --git a/api/dataservices/user/user.go b/api/dataservices/user/user.go index 8a7f7c051..1189f55b9 100644 --- a/api/dataservices/user/user.go +++ b/api/dataservices/user/user.go @@ -1,11 +1,12 @@ package user import ( + "errors" "fmt" "strings" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + dserrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -72,12 +73,12 @@ func (service *Service) UserByUsername(username string) (*portainer.User, error) return &portainer.User{}, nil }) - if err == stop { + if errors.Is(err, stop) { return u, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err diff --git a/api/dataservices/webhook/webhook.go b/api/dataservices/webhook/webhook.go index 1c47c477c..8dd40dafb 100644 --- a/api/dataservices/webhook/webhook.go +++ b/api/dataservices/webhook/webhook.go @@ -1,10 +1,11 @@ package webhook import ( + "errors" "fmt" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + dserrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -93,12 +94,12 @@ func (service *Service) WebhookByResourceID(ID string) (*portainer.Webhook, erro return &portainer.Webhook{}, nil }) - if err == stop { + if errors.Is(err, stop) { return w, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err @@ -127,12 +128,12 @@ func (service *Service) WebhookByToken(token string) (*portainer.Webhook, error) return &portainer.Webhook{}, nil }) - if err == stop { + if errors.Is(err, stop) { return w, nil } if err == nil { - return nil, errors.ErrObjectNotFound + return nil, dserrors.ErrObjectNotFound } return nil, err diff --git a/api/datastore/backup.go b/api/datastore/backup.go index b98c86740..a34e26786 100644 --- a/api/datastore/backup.go +++ b/api/datastore/backup.go @@ -115,7 +115,7 @@ func (store *Store) backupWithOptions(options *BackupOptions) (string, error) { if err := store.Close(); err != nil { return options.BackupPath, fmt.Errorf( - "error closing datastore before creating backup: %v", + "error closing datastore before creating backup: %w", err, ) } @@ -126,7 +126,7 @@ func (store *Store) backupWithOptions(options *BackupOptions) (string, error) { if _, err := store.Open(); err != nil { return options.BackupPath, fmt.Errorf( - "error opening datastore after creating backup: %v", + "error opening datastore after creating backup: %w", err, ) } diff --git a/api/datastore/datastore.go b/api/datastore/datastore.go index 510697c69..9703cde8e 100644 --- a/api/datastore/datastore.go +++ b/api/datastore/datastore.go @@ -1,6 +1,7 @@ package datastore import ( + "errors" "fmt" "io" "os" @@ -104,7 +105,7 @@ func (store *Store) edition() portainer.SoftwareEdition { // TODO: move the use of this to dataservices.IsErrObjectNotFound()? func (store *Store) IsErrObjectNotFound(e error) bool { - return e == portainerErrors.ErrObjectNotFound + return errors.Is(e, portainerErrors.ErrObjectNotFound) } func (store *Store) Connection() portainer.Connection { diff --git a/api/datastore/migrate_data_test.go b/api/datastore/migrate_data_test.go index 7fdd502a8..81e175c59 100644 --- a/api/datastore/migrate_data_test.go +++ b/api/datastore/migrate_data_test.go @@ -288,7 +288,7 @@ func migrateDBTestHelper(t *testing.T, srcPath, wantPath string, overrideInstanc // Convert database back to json. databasePath := con.GetDatabaseFilePath() if _, err := os.Stat(databasePath); err != nil { - return fmt.Errorf("stat on %s failed: %s", databasePath, err) + return fmt.Errorf("stat on %s failed: %w", databasePath, err) } gotJSON, err := con.ExportJSON(databasePath, false) diff --git a/api/datastore/migrator/migrate_dbversion26.go b/api/datastore/migrator/migrate_dbversion26.go index 64b80261a..bdc2674c6 100644 --- a/api/datastore/migrator/migrate_dbversion26.go +++ b/api/datastore/migrator/migrate_dbversion26.go @@ -2,7 +2,7 @@ package migrator import ( portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/stacks/stackutils" "github.com/rs/zerolog/log" @@ -25,7 +25,7 @@ func (m *Migrator) updateStackResourceControlToDB27() error { stack, err := m.stackService.StackByName(stackName) if err != nil { - if err == errors.ErrObjectNotFound { + if dataservices.IsErrObjectNotFound(err) { continue } diff --git a/api/datastore/migrator/migrate_dbversion31.go b/api/datastore/migrator/migrate_dbversion31.go index ec826f672..04f913788 100644 --- a/api/datastore/migrator/migrate_dbversion31.go +++ b/api/datastore/migrator/migrate_dbversion31.go @@ -4,7 +4,7 @@ import ( "fmt" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/internal/endpointutils" snapshotutils "github.com/portainer/portainer/api/internal/snapshot" @@ -86,7 +86,7 @@ func (m *Migrator) updateDockerhubToDB32() error { log.Info().Msg("updating dockerhub") dockerhub, err := m.dockerhubService.DockerHub() - if err == errors.ErrObjectNotFound { + if dataservices.IsErrObjectNotFound(err) { return nil } else if err != nil { return err diff --git a/api/datastore/migrator/migrate_dbversion71.go b/api/datastore/migrator/migrate_dbversion71.go index d860adf8d..815f7de21 100644 --- a/api/datastore/migrator/migrate_dbversion71.go +++ b/api/datastore/migrator/migrate_dbversion71.go @@ -1,7 +1,7 @@ package migrator import ( - "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" "github.com/rs/zerolog/log" ) @@ -19,7 +19,7 @@ func (m *Migrator) migrateDBVersionToDB71() error { if err == nil { log.Debug().Int("endpoint_id", int(s.EndpointID)).Msg("keeping snapshot") continue - } else if err != errors.ErrObjectNotFound { + } else if !dataservices.IsErrObjectNotFound(err) { log.Debug().Int("endpoint_id", int(s.EndpointID)).Err(err).Msg("database error") return err } diff --git a/api/datastore/migrator/migrate_dbversion90.go b/api/datastore/migrator/migrate_dbversion90.go index fe107188d..be8d766d7 100644 --- a/api/datastore/migrator/migrate_dbversion90.go +++ b/api/datastore/migrator/migrate_dbversion90.go @@ -4,7 +4,7 @@ import ( "github.com/rs/zerolog/log" portainer "github.com/portainer/portainer/api" - portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" ) func (m *Migrator) migrateDBVersionToDB90() error { @@ -30,7 +30,7 @@ func (m *Migrator) updateEdgeStackStatusForDB90() error { for _, edgeJob := range edgeJobs { for endpointId := range edgeJob.Endpoints { _, err := m.endpointService.Endpoint(endpointId) - if err == portainerDsErrors.ErrObjectNotFound { + if dataservices.IsErrObjectNotFound(err) { delete(edgeJob.Endpoints, endpointId) err = m.edgeJobService.UpdateEdgeJob(edgeJob.ID, &edgeJob) diff --git a/api/docker/snapshot.go b/api/docker/snapshot.go index a6e090a65..92a2849e7 100644 --- a/api/docker/snapshot.go +++ b/api/docker/snapshot.go @@ -178,6 +178,7 @@ func snapshotContainers(snapshot *portainer.DockerSnapshot, cli *client.Client) } else { var gpuOptions *_container.DeviceRequest = nil for _, deviceRequest := range response.HostConfig.Resources.DeviceRequests { + deviceRequest := deviceRequest if deviceRequest.Driver == "nvidia" || deviceRequest.Capabilities[0][0] == "gpu" { gpuOptions = &deviceRequest } diff --git a/api/git/backup.go b/api/git/backup.go index df1946c0d..45c45cdf1 100644 --- a/api/git/backup.go +++ b/api/git/backup.go @@ -53,7 +53,7 @@ func CloneWithBackup(gitService portainer.GitService, fileService portainer.File log.Warn().Err(restoreError).Msg("failed restoring backup folder") } - if err == gittypes.ErrAuthenticationFailure { + if errors.Is(err, gittypes.ErrAuthenticationFailure) { return cleanFn, errors.WithMessage(err, ErrInvalidGitCredential.Error()) } diff --git a/api/http/handler/edgegroups/handler.go b/api/http/handler/edgegroups/handler.go index 3e1a44e74..8f9bcc44f 100644 --- a/api/http/handler/edgegroups/handler.go +++ b/api/http/handler/edgegroups/handler.go @@ -1,6 +1,7 @@ package edgegroups import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -39,8 +40,9 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler { func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError { if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/edgejobs/edgejob_delete.go b/api/http/handler/edgejobs/edgejob_delete.go index 55c4c6ad4..23e921f89 100644 --- a/api/http/handler/edgejobs/edgejob_delete.go +++ b/api/http/handler/edgejobs/edgejob_delete.go @@ -1,6 +1,7 @@ package edgejobs import ( + "errors" "net/http" "strconv" @@ -42,8 +43,9 @@ func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *h } if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/edgejobs/edgejob_tasklogs_clear.go b/api/http/handler/edgejobs/edgejob_tasklogs_clear.go index 67ee57296..d71e3e91e 100644 --- a/api/http/handler/edgejobs/edgejob_tasklogs_clear.go +++ b/api/http/handler/edgejobs/edgejob_tasklogs_clear.go @@ -1,6 +1,7 @@ package edgejobs import ( + "errors" "net/http" "strconv" @@ -75,8 +76,9 @@ func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request } if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/edgejobs/edgejob_tasklogs_collect.go b/api/http/handler/edgejobs/edgejob_tasklogs_collect.go index c182f82f5..0bf5952ff 100644 --- a/api/http/handler/edgejobs/edgejob_tasklogs_collect.go +++ b/api/http/handler/edgejobs/edgejob_tasklogs_collect.go @@ -1,6 +1,7 @@ package edgejobs import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -83,8 +84,9 @@ func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Reque }) if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/edgejobs/handler.go b/api/http/handler/edgejobs/handler.go index a4bdcb94b..b4f925bc0 100644 --- a/api/http/handler/edgejobs/handler.go +++ b/api/http/handler/edgejobs/handler.go @@ -1,6 +1,7 @@ package edgejobs import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -62,8 +63,9 @@ func convertEndpointsToMetaObject(endpoints []portainer.EndpointID) map[portaine func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError { if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/endpoints/endpoint_registries_list.go b/api/http/handler/endpoints/endpoint_registries_list.go index 87eefddb7..2938e5c0f 100644 --- a/api/http/handler/endpoints/endpoint_registries_list.go +++ b/api/http/handler/endpoints/endpoint_registries_list.go @@ -153,8 +153,8 @@ func registryAccessPoliciesContainsNamespace(registryAccess portainer.RegistryAc func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User) ([]portainer.Registry, *httperror.HandlerError) { err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) - if err == security.ErrAuthorizationRequired { - return nil, httperror.Forbidden("User is not authorized", errors.New("missing namespace query parameter")) + if errors.Is(err, security.ErrAuthorizationRequired) { + return nil, httperror.Forbidden("User is not authorized", err) } if err != nil { return nil, httperror.InternalServerError("Unable to retrieve info from request context", err) diff --git a/api/http/handler/gitops/git_repo_file_preview.go b/api/http/handler/gitops/git_repo_file_preview.go index 6d1218411..227fadd83 100644 --- a/api/http/handler/gitops/git_repo_file_preview.go +++ b/api/http/handler/gitops/git_repo_file_preview.go @@ -29,7 +29,7 @@ type repositoryFilePreviewPayload struct { func (payload *repositoryFilePreviewPayload) Validate(r *http.Request) error { if govalidator.IsNull(payload.Repository) || !govalidator.IsURL(payload.Repository) { - return errors.New("Invalid repository URL. Must correspond to a valid URL format") + return errors.New("invalid repository URL. Must correspond to a valid URL format") } if govalidator.IsNull(payload.Reference) { @@ -37,7 +37,7 @@ func (payload *repositoryFilePreviewPayload) Validate(r *http.Request) error { } if govalidator.IsNull(payload.TargetFile) { - return errors.New("Invalid target filename.") + return errors.New("invalid target filename") } return nil @@ -70,11 +70,11 @@ func (handler *Handler) gitOperationRepoFilePreview(w http.ResponseWriter, r *ht err = handler.gitService.CloneRepository(projectPath, payload.Repository, payload.Reference, payload.Username, payload.Password, payload.TLSSkipVerify) if err != nil { - if err == gittypes.ErrAuthenticationFailure { + if errors.Is(err, gittypes.ErrAuthenticationFailure) { return httperror.BadRequest("Invalid git credential", err) } - newErr := fmt.Errorf("unable to clone git repository: %w", err) + newErr := fmt.Errorf("unable to clone git repository, error: %w", err) return httperror.InternalServerError(newErr.Error(), newErr) } diff --git a/api/http/handler/hostmanagement/openamt/amtactivation.go b/api/http/handler/hostmanagement/openamt/amtactivation.go index d3dab5e43..0fd5c5066 100644 --- a/api/http/handler/hostmanagement/openamt/amtactivation.go +++ b/api/http/handler/hostmanagement/openamt/amtactivation.go @@ -9,7 +9,6 @@ import ( "github.com/portainer/libhttp/request" "github.com/portainer/libhttp/response" portainer "github.com/portainer/portainer/api" - bolterrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/portainer/portainer/api/internal/endpointutils" ) @@ -33,7 +32,7 @@ func (handler *Handler) openAMTActivate(w http.ResponseWriter, r *http.Request) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) - if err == bolterrors.ErrObjectNotFound { + if handler.DataStore.IsErrObjectNotFound(err) { return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) diff --git a/api/http/handler/hostmanagement/openamt/amtdevices.go b/api/http/handler/hostmanagement/openamt/amtdevices.go index 69c474e83..aa99c04de 100644 --- a/api/http/handler/hostmanagement/openamt/amtdevices.go +++ b/api/http/handler/hostmanagement/openamt/amtdevices.go @@ -8,7 +8,6 @@ import ( "github.com/portainer/libhttp/request" "github.com/portainer/libhttp/response" portainer "github.com/portainer/portainer/api" - bolterrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/rs/zerolog/log" ) @@ -33,7 +32,7 @@ func (handler *Handler) openAMTDevices(w http.ResponseWriter, r *http.Request) * } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) - if err == bolterrors.ErrObjectNotFound { + if handler.DataStore.IsErrObjectNotFound(err) { return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) diff --git a/api/http/handler/hostmanagement/openamt/amtrpc.go b/api/http/handler/hostmanagement/openamt/amtrpc.go index f15763a8b..1d4176db9 100644 --- a/api/http/handler/hostmanagement/openamt/amtrpc.go +++ b/api/http/handler/hostmanagement/openamt/amtrpc.go @@ -12,7 +12,6 @@ import ( "github.com/portainer/libhttp/request" "github.com/portainer/libhttp/response" portainer "github.com/portainer/portainer/api" - bolterrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/portainer/portainer/api/hostmanagement/openamt" "github.com/docker/docker/api/types" @@ -63,7 +62,7 @@ func (handler *Handler) openAMTHostInfo(w http.ResponseWriter, r *http.Request) log.Info().Int("endpointID", endpointID).Msg("OpenAMTHostInfo") endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) - if err == bolterrors.ErrObjectNotFound { + if handler.DataStore.IsErrObjectNotFound(err) { return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) diff --git a/api/http/handler/kubernetes/handler.go b/api/http/handler/kubernetes/handler.go index da575e894..19927fbc1 100644 --- a/api/http/handler/kubernetes/handler.go +++ b/api/http/handler/kubernetes/handler.go @@ -7,7 +7,6 @@ import ( "strconv" portainer "github.com/portainer/portainer/api" - portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/portainer/portainer/api/kubernetes" "github.com/gorilla/mux" @@ -121,7 +120,7 @@ func (handler *Handler) kubeClient(next http.Handler) http.Handler { } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) - if err == portainerDsErrors.ErrObjectNotFound { + if handler.DataStore.IsErrObjectNotFound(err) { httperror.WriteError( w, http.StatusNotFound, diff --git a/api/http/handler/kubernetes/ingresses.go b/api/http/handler/kubernetes/ingresses.go index 0d577930d..1e03ed7ee 100644 --- a/api/http/handler/kubernetes/ingresses.go +++ b/api/http/handler/kubernetes/ingresses.go @@ -8,7 +8,6 @@ import ( "github.com/portainer/libhttp/request" "github.com/portainer/libhttp/response" portainer "github.com/portainer/portainer/api" - portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors" models "github.com/portainer/portainer/api/http/models/kubernetes" "github.com/portainer/portainer/api/http/security" ) @@ -23,7 +22,7 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) - if err == portainerDsErrors.ErrObjectNotFound { + if handler.DataStore.IsErrObjectNotFound(err) { return httperror.NotFound( "Unable to find an environment with the specified identifier inside the database", err, diff --git a/api/http/handler/stacks/webhook_invoke.go b/api/http/handler/stacks/webhook_invoke.go index 77f64a0bc..b73b6888d 100644 --- a/api/http/handler/stacks/webhook_invoke.go +++ b/api/http/handler/stacks/webhook_invoke.go @@ -1,6 +1,7 @@ package stacks import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -38,7 +39,8 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h } if err = deployments.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService); err != nil { - if _, ok := err.(*deployments.StackAuthorMissingErr); ok { + var StackAuthorMissingErr *deployments.StackAuthorMissingErr + if errors.As(err, &StackAuthorMissingErr) { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err} } diff --git a/api/http/handler/tags/handler.go b/api/http/handler/tags/handler.go index e1dd9423c..d72b7b0d3 100644 --- a/api/http/handler/tags/handler.go +++ b/api/http/handler/tags/handler.go @@ -1,6 +1,7 @@ package tags import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -34,8 +35,9 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler { func txResponse(w http.ResponseWriter, r any, err error) *httperror.HandlerError { if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/tags/tag_delete.go b/api/http/handler/tags/tag_delete.go index 2e8107956..48dffec92 100644 --- a/api/http/handler/tags/tag_delete.go +++ b/api/http/handler/tags/tag_delete.go @@ -1,6 +1,7 @@ package tags import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -41,8 +42,9 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe } if err != nil { - if httpErr, ok := err.(*httperror.HandlerError); ok { - return httpErr + var handlerError *httperror.HandlerError + if errors.As(err, &handlerError) { + return handlerError } return httperror.InternalServerError("Unexpected error", err) diff --git a/api/http/handler/users/user_remove_access_token.go b/api/http/handler/users/user_remove_access_token.go index be13ccad5..99635621c 100644 --- a/api/http/handler/users/user_remove_access_token.go +++ b/api/http/handler/users/user_remove_access_token.go @@ -1,6 +1,7 @@ package users import ( + "errors" "net/http" httperror "github.com/portainer/libhttp/error" @@ -66,7 +67,7 @@ func (handler *Handler) userRemoveAccessToken(w http.ResponseWriter, r *http.Req err = handler.apiKeyService.DeleteAPIKey(portainer.APIKeyID(apiKeyID)) if err != nil { - if err == apikey.ErrInvalidAPIKey { + if errors.Is(err, apikey.ErrInvalidAPIKey) { return httperror.NotFound("Unable to find an api-key with the specified identifier inside the database", err) } return httperror.InternalServerError("Unable to remove the api-key from the user", err) diff --git a/api/http/handler/websocket/hijack.go b/api/http/handler/websocket/hijack.go index a991f3bec..ca9ae26cc 100644 --- a/api/http/handler/websocket/hijack.go +++ b/api/http/handler/websocket/hijack.go @@ -1,6 +1,7 @@ package websocket import ( + "errors" "fmt" "net/http" "net/http/httputil" @@ -11,7 +12,7 @@ import ( func hijackRequest(websocketConn *websocket.Conn, httpConn *httputil.ClientConn, request *http.Request) error { // Server hijacks the connection, error 'connection closed' expected resp, err := httpConn.Do(request) - if err != httputil.ErrPersistEOF { + if !errors.Is(err, httputil.ErrPersistEOF) { if err != nil { return err } diff --git a/api/http/middlewares/withitem.go b/api/http/middlewares/withitem.go index c42d95749..3229d555c 100644 --- a/api/http/middlewares/withitem.go +++ b/api/http/middlewares/withitem.go @@ -8,7 +8,7 @@ import ( "github.com/gorilla/mux" httperror "github.com/portainer/libhttp/error" "github.com/portainer/libhttp/request" - bolterrors "github.com/portainer/portainer/api/dataservices/errors" + "github.com/portainer/portainer/api/dataservices" ) type ItemContextKey string @@ -31,7 +31,7 @@ func WithItem[TId ~int, TObject any](getter ItemGetter[TId, TObject], idParam st item, err := getter(TId(itemId)) if err != nil { statusCode := http.StatusInternalServerError - if err == bolterrors.ErrObjectNotFound { + if dataservices.IsErrObjectNotFound(err) { statusCode = http.StatusNotFound } httperror.WriteError(rw, statusCode, "Unable to find a object with the specified identifier inside the database", err) diff --git a/api/http/proxy/factory/docker/registry.go b/api/http/proxy/factory/docker/registry.go index 352c5a459..0c3d3cfac 100644 --- a/api/http/proxy/factory/docker/registry.go +++ b/api/http/proxy/factory/docker/registry.go @@ -37,6 +37,7 @@ func createRegistryAuthenticationHeader( } else { // any "custom" registry var matchingRegistry *portainer.Registry for _, registry := range accessContext.registries { + registry := registry if registry.ID == registryId && (accessContext.isAdmin || security.AuthorizedRegistryAccess(®istry, accessContext.user, accessContext.teamMemberships, accessContext.endpointID)) { diff --git a/api/http/proxy/factory/docker/transport.go b/api/http/proxy/factory/docker/transport.go index a2d85cfa8..57195a060 100644 --- a/api/http/proxy/factory/docker/transport.go +++ b/api/http/proxy/factory/docker/transport.go @@ -15,7 +15,6 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/dataservices" - dataerrors "github.com/portainer/portainer/api/dataservices/errors" "github.com/portainer/portainer/api/docker" "github.com/portainer/portainer/api/http/proxy/factory/utils" "github.com/portainer/portainer/api/http/security" @@ -647,7 +646,7 @@ func (transport *Transport) executeGenericResourceDeletionOperation(request *htt if response.StatusCode == http.StatusNoContent || response.StatusCode == http.StatusOK { resourceControl, err := transport.dataStore.ResourceControl().ResourceControlByResourceIDAndType(resourceIdentifierAttribute, resourceType) if err != nil { - if err == dataerrors.ErrObjectNotFound { + if dataservices.IsErrObjectNotFound(err) { return response, nil } diff --git a/api/internal/edge/edgestack.go b/api/internal/edge/edgestack.go index 78789cdc3..83dd99617 100644 --- a/api/internal/edge/edgestack.go +++ b/api/internal/edge/edgestack.go @@ -18,6 +18,7 @@ func EdgeStackRelatedEndpoints(edgeGroupIDs []portainer.EdgeGroupID, endpoints [ var edgeGroup *portainer.EdgeGroup for _, group := range edgeGroups { + group := group if group.ID == edgeGroupID { edgeGroup = &group break diff --git a/api/internal/edge/edgestacks/service.go b/api/internal/edge/edgestacks/service.go index 878bfd0af..863f186ed 100644 --- a/api/internal/edge/edgestacks/service.go +++ b/api/internal/edge/edgestacks/service.go @@ -81,7 +81,7 @@ func (service *Service) PersistEdgeStack( relatedEndpointIds, err := edge.EdgeStackRelatedEndpoints(stack.EdgeGroups, relationConfig.Endpoints, relationConfig.EndpointGroups, relationConfig.EdgeGroups) if err != nil { - if err == edge.ErrEdgeGroupNotFound { + if errors.Is(err, edge.ErrEdgeGroupNotFound) { return nil, httperrors.NewInvalidPayloadError(err.Error()) } return nil, fmt.Errorf("unable to persist environment relation in database: %w", err) diff --git a/api/kubernetes/cli/exec.go b/api/kubernetes/cli/exec.go index d8fdd4401..557857d65 100644 --- a/api/kubernetes/cli/exec.go +++ b/api/kubernetes/cli/exec.go @@ -1,6 +1,7 @@ package cli import ( + "context" "errors" "io" @@ -50,13 +51,14 @@ func (kcl *KubeClient) StartExecProcess(token string, useAdminToken bool, namesp return } - err = exec.Stream(remotecommand.StreamOptions{ + err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{ Stdin: stdin, Stdout: stdout, Tty: true, }) if err != nil { - if _, ok := err.(utilexec.ExitError); !ok { + var exitError utilexec.ExitError + if !errors.As(err, &exitError) { errChan <- errors.New("unable to start exec process") } } diff --git a/api/kubernetes/cli/pod_test.go b/api/kubernetes/cli/pod_test.go index f7911a0f6..f363ac1b6 100644 --- a/api/kubernetes/cli/pod_test.go +++ b/api/kubernetes/cli/pod_test.go @@ -2,6 +2,7 @@ package cli import ( "context" + "errors" "testing" "time" @@ -30,7 +31,7 @@ func Test_waitForPodStatus(t *testing.T) { ctx, cancel := context.WithCancel(context.TODO()) cancel() err := k.waitForPodStatus(ctx, v1.PodRunning, podSpec) - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Errorf("waitForPodStatus should throw context cancellation error; err=%s", err) } }) @@ -59,7 +60,7 @@ func Test_waitForPodStatus(t *testing.T) { ctx, cancelFunc := context.WithTimeout(context.TODO(), 0*time.Second) defer cancelFunc() err = k.waitForPodStatus(ctx, v1.PodRunning, podSpec) - if err != context.DeadlineExceeded { + if !errors.Is(err, context.DeadlineExceeded) { t.Errorf("waitForPodStatus should throw deadline exceeded error; err=%s", err) } }) diff --git a/api/scheduler/scheduler.go b/api/scheduler/scheduler.go index 328e69999..82e06ccec 100644 --- a/api/scheduler/scheduler.go +++ b/api/scheduler/scheduler.go @@ -55,7 +55,7 @@ func (s *Scheduler) Shutdown() error { s.mu.Unlock() err := ctx.Err() - if err == context.Canceled { + if errors.Is(err, context.Canceled) { return nil } return err diff --git a/api/stacks/stackutils/gitops.go b/api/stacks/stackutils/gitops.go index 6c3a18502..e80d38da7 100644 --- a/api/stacks/stackutils/gitops.go +++ b/api/stacks/stackutils/gitops.go @@ -27,7 +27,7 @@ func DownloadGitRepository(config gittypes.RepoConfig, gitService portainer.GitS projectPath := getProjectPath() err := gitService.CloneRepository(projectPath, config.URL, config.ReferenceName, username, password, config.TLSSkipVerify) if err != nil { - if err == gittypes.ErrAuthenticationFailure { + if errors.Is(err, gittypes.ErrAuthenticationFailure) { newErr := ErrInvalidGitCredential return "", newErr } diff --git a/golangci-lint.sh b/golangci-lint.sh old mode 100644 new mode 100755 index ee9fef358..412146787 --- a/golangci-lint.sh +++ b/golangci-lint.sh @@ -2,10 +2,10 @@ #!/bin/bash cd api -if golangci-lint run -c .golangci.yaml +if golangci-lint run --timeout=10m -c .golangci.yaml then echo "golangci-lint run successfully" else echo "golangci-lint run failed" exit 1 -fi \ No newline at end of file +fi