mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:51:50 +00:00
chore: Change errors.HasType to respect multi-errors (#63024)
With this patch, the `errors.HasType` API behaves similar to `Is` and `As`, where it checks the full error tree instead of just checking a linearized version of it, as cockroachdb/errors's `HasType` implementation does not respect multi-errors. As a consequence, a bunch of relationships between HasType and Is/As that you'd intuitively expect to hold are now true; see changes to `invariants_test.go`.
This commit is contained in:
parent
9183f528c7
commit
2955bb6cfb
@ -290,7 +290,7 @@ func (s *sourcesSyncHandler) Handle(ctx context.Context) (err error) {
|
||||
// If another instance is working on background syncs, we don't want to
|
||||
// do anything. We should check every time still in case the current worker
|
||||
// goes offline, we want to be ready to pick up the work.
|
||||
if err := s.rmux.LockContext(ctx); errors.HasType(err, &redsync.ErrTaken{}) {
|
||||
if err := s.rmux.LockContext(ctx); errors.HasType[*redsync.ErrTaken](err) {
|
||||
skippedReason = fmt.Sprintf("did not acquire lock, another worker is likely active: %s", err.Error())
|
||||
handleLogger.Debug(skippedReason)
|
||||
return nil // ignore lock contention errors
|
||||
|
||||
@ -181,7 +181,7 @@ func ListLimitsHandler(baseLogger log.Logger, redisStore limiter.RedisStore) htt
|
||||
// Capture the current usage.
|
||||
currentUsage, expiry, err := l.Usage(r.Context())
|
||||
if err != nil {
|
||||
if errors.HasType(err, limiter.NoAccessError{}) {
|
||||
if errors.HasType[limiter.NoAccessError](err) {
|
||||
// No access to this feature, skip.
|
||||
continue
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ func setupLoopDevice(
|
||||
// add the error to the bottom of the step's log output,
|
||||
// but only if this isnt from exec.Command, as those get added
|
||||
// by our logging wrapper
|
||||
if !errors.HasType(err, &exec.ExitError{}) {
|
||||
if !errors.HasType[*exec.ExitError](err) {
|
||||
fmt.Fprint(handle, err.Error())
|
||||
}
|
||||
handle.Finalize(1)
|
||||
|
||||
@ -93,7 +93,7 @@ func (r *GitCommitResolver) resolveCommit(ctx context.Context) (*gitdomain.Commi
|
||||
}
|
||||
|
||||
r.commit, r.commitErr = r.gitserverClient.GetCommit(ctx, r.gitRepo, api.CommitID(r.oid))
|
||||
if r.commitErr != nil && errors.HasType(r.commitErr, &gitdomain.RevisionNotFoundError{}) {
|
||||
if r.commitErr != nil && errors.HasType[*gitdomain.RevisionNotFoundError](r.commitErr) {
|
||||
// If the commit is not found, attempt to do a ensure revision call.
|
||||
_, err := r.gitserverClient.ResolveRevision(ctx, r.gitRepo, string(r.oid), gitserver.ResolveRevisionOptions{EnsureRevision: true})
|
||||
if err != nil {
|
||||
|
||||
@ -52,7 +52,7 @@ func getUserToInviteToOrganization(ctx context.Context, db database.DB, username
|
||||
|
||||
if _, err := db.OrgMembers().GetByOrgIDAndUserID(ctx, orgID, userToInvite.ID); err == nil {
|
||||
return nil, "", errors.New("user is already a member of the organization")
|
||||
} else if !errors.HasType(err, &database.ErrOrgMemberNotFound{}) {
|
||||
} else if !errors.HasType[*database.ErrOrgMemberNotFound](err) {
|
||||
return nil, "", err
|
||||
}
|
||||
return userToInvite, userEmailAddress, nil
|
||||
|
||||
@ -110,7 +110,7 @@ index 9bd8209..d2acfa9 100644
|
||||
if err == nil {
|
||||
t.Fatal("unexpected empty err")
|
||||
}
|
||||
if !errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if !errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
t.Fatalf("incorrect err returned %T", err)
|
||||
}
|
||||
})
|
||||
|
||||
@ -300,7 +300,7 @@ func (r *RepositoryResolver) Commit(ctx context.Context, args *RepositoryCommitA
|
||||
|
||||
commitID, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).ResolveRev(ctx, r.name, args.Rev)
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
@ -401,7 +401,7 @@ func (r *RepositoryResolver) FirstEverCommit(ctx context.Context) (_ *GitCommitR
|
||||
|
||||
commit, err := r.gitserverClient.FirstEverCommit(ctx, repo.Name)
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
@ -649,7 +649,7 @@ func (r *schemaResolver) ResolvePhabricatorDiff(ctx context.Context, args *struc
|
||||
}
|
||||
|
||||
// If we already created the commit
|
||||
if commit, err := getCommit(); commit != nil || (err != nil && !errors.HasType(err, &gitdomain.RevisionNotFoundError{})) {
|
||||
if commit, err := getCommit(); commit != nil || (err != nil && !errors.HasType[*gitdomain.RevisionNotFoundError](err)) {
|
||||
return commit, err
|
||||
}
|
||||
|
||||
|
||||
@ -190,7 +190,7 @@ func newCommon(w http.ResponseWriter, r *http.Request, db database.DB, title str
|
||||
// Common repo pages (blob, tree, etc).
|
||||
var err error
|
||||
common.Repo, common.CommitID, err = handlerutil.GetRepoAndRev(r.Context(), logger, db, mux.Vars(r))
|
||||
isRepoEmptyError := routevar.ToRepoRev(mux.Vars(r)).Rev == "" && errors.HasType(err, &gitdomain.RevisionNotFoundError{}) // should reply with HTTP 200
|
||||
isRepoEmptyError := routevar.ToRepoRev(mux.Vars(r)).Rev == "" && errors.HasType[*gitdomain.RevisionNotFoundError](err) // should reply with HTTP 200
|
||||
if err != nil && !isRepoEmptyError {
|
||||
var urlMovedError *handlerutil.URLMovedError
|
||||
if errors.As(err, &urlMovedError) {
|
||||
@ -214,12 +214,12 @@ func newCommon(w http.ResponseWriter, r *http.Request, db database.DB, title str
|
||||
http.Redirect(w, r, u.String(), http.StatusSeeOther)
|
||||
return nil, nil
|
||||
}
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
// Revision does not exist.
|
||||
serveError(w, r, db, err, http.StatusNotFound)
|
||||
return nil, nil
|
||||
}
|
||||
if errors.HasType(err, &gitserver.RepoNotCloneableErr{}) {
|
||||
if errors.HasType[*gitserver.RepoNotCloneableErr](err) {
|
||||
if errcode.IsNotFound(err) {
|
||||
// Repository is not found.
|
||||
serveError(w, r, db, err, http.StatusNotFound)
|
||||
|
||||
@ -24,7 +24,7 @@ func TestGetRepo(t *testing.T) {
|
||||
})
|
||||
|
||||
_, err := GetRepo(context.Background(), logger, dbmocks.NewMockDB(), map[string]string{"Repo": "repo1"})
|
||||
if !errors.HasType(err, &URLMovedError{}) {
|
||||
if !errors.HasType[*URLMovedError](err) {
|
||||
t.Fatalf("err: want type *URLMovedError but got %T", err)
|
||||
}
|
||||
})
|
||||
|
||||
@ -145,7 +145,7 @@ func AccessTokenAuthMiddleware(db database.DB, baseLogger log.Logger, next http.
|
||||
|
||||
subjectUserID, err := db.AccessTokens().Lookup(r.Context(), token, opts)
|
||||
if err != nil {
|
||||
if err == database.ErrAccessTokenNotFound || errors.HasType(err, database.InvalidTokenError{}) {
|
||||
if err == database.ErrAccessTokenNotFound || errors.HasType[database.InvalidTokenError](err) {
|
||||
anonymousId, anonCookieSet := cookie.AnonymousUID(r)
|
||||
if !anonCookieSet {
|
||||
anonymousId = fmt.Sprintf("unknown user @ %s", time.Now()) // we don't have a reliable user identifier at the time of the failure
|
||||
|
||||
@ -41,9 +41,9 @@ func handleStreamBlame(logger log.Logger, db database.DB, gitserverClient gitser
|
||||
|
||||
repo, commitID, err := handlerutil.GetRepoAndRev(r.Context(), logger, db, mux.Vars(r))
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
} else if errors.HasType(err, &gitserver.RepoNotCloneableErr{}) && errcode.IsNotFound(err) {
|
||||
} else if errors.HasType[*gitserver.RepoNotCloneableErr](err) && errcode.IsNotFound(err) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
} else if errcode.IsNotFound(err) || errcode.IsBlocked(err) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
@ -15,7 +15,7 @@ func validateNotebookWritePermissionsForUser(ctx context.Context, db database.DB
|
||||
} else if notebook.NamespaceOrgID != 0 {
|
||||
// Only members of the org have write access to the notebook
|
||||
membership, err := db.OrgMembers().GetByOrgIDAndUserID(ctx, notebook.NamespaceOrgID, userID)
|
||||
if errors.HasType(err, &database.ErrOrgMemberNotFound{}) || membership == nil {
|
||||
if errors.HasType[*database.ErrOrgMemberNotFound](err) || membership == nil {
|
||||
return errors.New("user is not a member of the notebook organization namespace")
|
||||
} else if err != nil {
|
||||
return err
|
||||
|
||||
@ -431,7 +431,7 @@ func (r *notebookResolver) Namespace(ctx context.Context) (*graphqlbackend.Names
|
||||
// On Cloud, the user can have access to an org notebook if it is public. But if the user is not a member of
|
||||
// that org, then he does not have access to further information about the org. Instead of returning an error
|
||||
// (which would prevent the user from viewing the notebook) we return an empty namespace.
|
||||
if dotcom.SourcegraphDotComMode() && errors.HasType(err, &database.OrgNotFoundError{}) {
|
||||
if dotcom.SourcegraphDotComMode() && errors.HasType[*database.OrgNotFoundError](err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
|
||||
@ -200,7 +200,7 @@ func (h *streamHandler) serveHTTP(r *http.Request, tr trace.Trace, eventWriter *
|
||||
return h.searchClient.Execute(ctx, batchedStream, inputs)
|
||||
}()
|
||||
|
||||
if err != nil && errors.HasType(err, &query.UnsupportedError{}) {
|
||||
if err != nil && errors.HasType[*query.UnsupportedError](err) {
|
||||
eventWriter.Alert(search.AlertForQuery(inputs.OriginalQuery, err))
|
||||
err = nil
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ func (wr *Router) HandleBitbucketCloudWebhook(logger log.Logger, w http.Response
|
||||
eventType := r.Header.Get("X-Event-Key")
|
||||
e, err := bitbucketcloud.ParseWebhookEvent(eventType, payload)
|
||||
if err != nil {
|
||||
if errors.HasType(err, bitbucketcloud.UnknownWebhookEventKey("")) {
|
||||
if errors.HasType[bitbucketcloud.UnknownWebhookEventKey](err) {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
||||
@ -155,13 +155,13 @@ func TestGitCLIBackend_ArchiveReader(t *testing.T) {
|
||||
t.Run("non existent commit", func(t *testing.T) {
|
||||
_, err := backend.ArchiveReader(ctx, "tar", "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", nil)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("non existent ref", func(t *testing.T) {
|
||||
_, err := backend.ArchiveReader(ctx, "tar", "head-2", nil)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
// Verify that if the context is canceled, the reader returns an error.
|
||||
|
||||
@ -126,12 +126,12 @@ func TestGitCLIBackend_Blame(t *testing.T) {
|
||||
// Ambiguous ref, could be commit, could be a ref.
|
||||
_, err := backend.Blame(ctx, "deadbeef", "foo.txt", git.BlameOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Definitely a commit (yes, those yield different errors from git).
|
||||
_, err = backend.Blame(ctx, "e3889dff4263a2273459471739aafabc10269885", "foo.txt", git.BlameOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("file not found", func(t *testing.T) {
|
||||
|
||||
@ -93,7 +93,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
_ = it.Close()
|
||||
})
|
||||
|
||||
@ -346,7 +346,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Verify ordering doesn't matter and we return an error for any missing range:
|
||||
it, err = backend.CommitLog(ctx, git.CommitLogOpts{
|
||||
@ -355,7 +355,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Bad commit in range:
|
||||
it, err = backend.CommitLog(ctx, git.CommitLogOpts{
|
||||
@ -364,7 +364,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Bad commit in range LHS:
|
||||
it, err = backend.CommitLog(ctx, git.CommitLogOpts{
|
||||
@ -373,7 +373,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Bad ref in range:
|
||||
it, err = backend.CommitLog(ctx, git.CommitLogOpts{
|
||||
@ -382,7 +382,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Unknown SHA:
|
||||
it, err = backend.CommitLog(ctx, git.CommitLogOpts{
|
||||
@ -391,7 +391,7 @@ func TestGitCLIBackend_CommitLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
// Verify that if the context is canceled, the iterator returns an error.
|
||||
t.Run("context cancelation", func(t *testing.T) {
|
||||
|
||||
@ -142,25 +142,25 @@ func TestGitCLIBackend_ContributorCounts(t *testing.T) {
|
||||
Range: "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", // Invalid OID
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
_, err = backend.ContributorCounts(ctx, git.ContributorCountsOpts{
|
||||
Range: "unknownbranch", // Invalid ref
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
_, err = backend.ContributorCounts(ctx, git.ContributorCountsOpts{
|
||||
Range: "unknownbranch..HEAD", // Invalid left hand of range
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
_, err = backend.ContributorCounts(ctx, git.ContributorCountsOpts{
|
||||
Range: "HEAD..unknownbranch", // Invalid right hand of range
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -94,11 +94,11 @@ index 0000000000000000000000000000000000000000..8a6a2d098ecaf90105f1cf2fa90fc460
|
||||
|
||||
_, err := backend.RawDiff(ctx, "unknown", "test", git.GitDiffComparisonTypeOnlyInHead)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
_, err = backend.RawDiff(ctx, "test", "unknown", git.GitDiffComparisonTypeOnlyInHead)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
t.Run("files outside repository", func(t *testing.T) {
|
||||
// We use git-diff-tree, but with git-diff you can diff any files on disk
|
||||
@ -250,7 +250,7 @@ func TestGitCLIBackend_ChangedFiles(t *testing.T) {
|
||||
|
||||
_, err := backend.ChangedFiles(ctx, "invalid", "HEAD")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("invalid head", func(t *testing.T) {
|
||||
@ -264,7 +264,7 @@ func TestGitCLIBackend_ChangedFiles(t *testing.T) {
|
||||
|
||||
_, err := backend.ChangedFiles(ctx, "testbase", "invalid")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("empty base and single commit", func(t *testing.T) {
|
||||
|
||||
@ -71,7 +71,7 @@ func TestGitCLIBackend_RevParseHead(t *testing.T) {
|
||||
|
||||
_, err := backend.RevParseHead(ctx)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -67,10 +67,10 @@ func TestGitCLIBackend_MergeBase(t *testing.T) {
|
||||
|
||||
_, err := backend.MergeBase(ctx, "master", "notfound")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
_, err = backend.MergeBase(ctx, "notfound", "master")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -55,24 +55,24 @@ func TestGitCLIBackend_GetObject(t *testing.T) {
|
||||
// Unknown revision.
|
||||
_, err = backend.GetObject(ctx, "master2")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Unknown commit.
|
||||
_, err = backend.GetObject(ctx, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Invalid commit sha (invalid hex format).
|
||||
_, err = backend.GetObject(ctx, "notacommitsha")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
t.Run("HEAD in empty repo", func(t *testing.T) {
|
||||
backend := BackendWithRepoCommands(t)
|
||||
|
||||
_, err := backend.GetObject(ctx, "HEAD")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -300,7 +300,7 @@ func (g *gitCLIBackend) Stat(ctx context.Context, commit api.CommitID, path stri
|
||||
if path == "" || path == "." {
|
||||
rev, err := g.revParse(ctx, string(commit)+"^{tree}")
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, &os.PathError{Op: "ls-tree", Path: path, Err: os.ErrNotExist}
|
||||
}
|
||||
return nil, err
|
||||
|
||||
@ -69,7 +69,7 @@ func TestGitCLIBackend_ReadFile(t *testing.T) {
|
||||
t.Run("non existent commit", func(t *testing.T) {
|
||||
_, err := backend.ReadFile(ctx, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", "file1")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("special file paths", func(t *testing.T) {
|
||||
@ -195,7 +195,7 @@ func TestGitCLIBackend_GetCommit(t *testing.T) {
|
||||
t.Run("non existent commit", func(t *testing.T) {
|
||||
_, err := backend.GetCommit(ctx, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", false)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
// This test only exists because we sometimes pass non-commit ID strings to the
|
||||
@ -204,7 +204,7 @@ func TestGitCLIBackend_GetCommit(t *testing.T) {
|
||||
t.Run("bad revision", func(t *testing.T) {
|
||||
_, err := backend.GetCommit(ctx, "nonexisting", false)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
// This test only exists because we sometimes pass non-commit ID strings to the
|
||||
@ -214,7 +214,7 @@ func TestGitCLIBackend_GetCommit(t *testing.T) {
|
||||
backend := BackendWithRepoCommands(t)
|
||||
_, err := backend.GetCommit(ctx, "HEAD", false)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("read commit", func(t *testing.T) {
|
||||
@ -518,7 +518,7 @@ func TestGitCLIBackend_Stat(t *testing.T) {
|
||||
t.Run("non existent commit", func(t *testing.T) {
|
||||
_, err := backend.Stat(ctx, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", "file1")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("stat root", func(t *testing.T) {
|
||||
@ -745,13 +745,13 @@ func TestGitCLIBackend_ReadDir(t *testing.T) {
|
||||
t.Cleanup(func() { it.Close() })
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Read no entries:
|
||||
it, err = backend.ReadDir(ctx, "notfound", "nested", false)
|
||||
require.NoError(t, err)
|
||||
err = it.Close()
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("non existent commit", func(t *testing.T) {
|
||||
@ -761,7 +761,7 @@ func TestGitCLIBackend_ReadDir(t *testing.T) {
|
||||
_, err = it.Next()
|
||||
require.Error(t, err)
|
||||
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("read root", func(t *testing.T) {
|
||||
|
||||
@ -53,7 +53,7 @@ func TestGitCLIBackend_ResolveRevision(t *testing.T) {
|
||||
// Unknown commit:
|
||||
_, err = backend.ResolveRevision(ctx, "dfcb84e522cab3c0b307a70917604c6d3da00dc8")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Resolve abbrev commit:
|
||||
commit, err = backend.ResolveRevision(ctx, "f372e36")
|
||||
@ -62,7 +62,7 @@ func TestGitCLIBackend_ResolveRevision(t *testing.T) {
|
||||
// Unknown abbrev commit:
|
||||
_, err = backend.ResolveRevision(ctx, "dfcb84e5")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Resolve ref:
|
||||
commit, err = backend.ResolveRevision(ctx, "refs/heads/master")
|
||||
@ -81,32 +81,32 @@ func TestGitCLIBackend_ResolveRevision(t *testing.T) {
|
||||
// Unknown ref:
|
||||
_, err = backend.ResolveRevision(ctx, "refs/heads/notfound")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
_, err = backend.ResolveRevision(ctx, "notfound")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Resolve object that is not a commit: (this is the tree object of f372e36a91bc35e5d99df8be435bdcb1f0660bc5)
|
||||
_, err = backend.ResolveRevision(ctx, "92cb0143f5166452f2d45ed974a818749bc4a13f")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// :file1 gets the object ID of the file called file1 at HEAD.
|
||||
// We don't allow that, since it leaks the existence of the file.
|
||||
_, err = backend.ResolveRevision(ctx, ":file1")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// HEAD:file1 gets the object ID of the file called file1 at HEAD.
|
||||
// We don't allow that, since it leaks the existence of the file.
|
||||
_, err = backend.ResolveRevision(ctx, "HEAD:file1")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// :/foo gets a commit by commit message, but we don't want that.
|
||||
_, err = backend.ResolveRevision(ctx, ":/foo")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
// HEAD^{/foo} is the same as the above.
|
||||
// TODO: This currently passes, but it shouldn't need to.
|
||||
// _, err = backend.ResolveRevision(ctx, "HEAD^{/foo}")
|
||||
@ -120,7 +120,7 @@ func TestGitCLIBackend_ResolveRevision(t *testing.T) {
|
||||
// Not found range:
|
||||
_, err = backend.ResolveRevision(ctx, "master..notfound")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("HEAD in empty repo", func(t *testing.T) {
|
||||
@ -128,6 +128,6 @@ func TestGitCLIBackend_ResolveRevision(t *testing.T) {
|
||||
|
||||
_, err := backend.ResolveRevision(ctx, "HEAD")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -74,12 +74,12 @@ func TestGitCLIBackend_RevAtTime(t *testing.T) {
|
||||
// Invalid rev returns a rev not found error
|
||||
_, err = backend.RevAtTime(ctx, "noexist", time.Date(2048, 6, 1, 0, 0, 0, 0, time.UTC))
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
|
||||
// Invalid OID returns a rev not found error
|
||||
_, err = backend.RevAtTime(ctx, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", time.Date(2048, 6, 1, 0, 0, 0, 0, time.UTC))
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("out of order commit date", func(t *testing.T) {
|
||||
|
||||
@ -552,7 +552,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
MetricLabelValues: []string{name},
|
||||
Metrics: redMetrics,
|
||||
ErrorFilter: func(err error) observation.ErrorFilterBehaviour {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return observation.EmitForHoney | observation.EmitForTraces
|
||||
}
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
|
||||
@ -971,7 +971,7 @@ func (gs *grpcServer) ResolveRevision(ctx context.Context, req *proto.ResolveRev
|
||||
if err != nil {
|
||||
// If that fails to resolve the revspec, try to ensure the revision exists,
|
||||
// if requested by the caller.
|
||||
if req.GetEnsureRevision() && errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if req.GetEnsureRevision() && errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
// We ensured the revision exists, so try to resolve it again.
|
||||
if gs.svc.EnsureRevision(ctx, repoName, revspec) {
|
||||
sha, err = backend.ResolveRevision(ctx, revspec)
|
||||
|
||||
@ -151,5 +151,5 @@ func initializeUploadStore(ctx context.Context, uploadStore uploadstore.Store) e
|
||||
}
|
||||
|
||||
func isRequestError(err error) bool {
|
||||
return errors.HasType(err, &smithyhttp.RequestSendError{})
|
||||
return errors.HasType[*smithyhttp.RequestSendError](err)
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ func syncServices(ctx context.Context, services []*types.ExternalService, newRat
|
||||
for _, svc := range services {
|
||||
limit, err := extsvc.ExtractEncryptableRateLimit(ctx, svc.Config, svc.Kind)
|
||||
if err != nil {
|
||||
if errors.HasType(err, extsvc.ErrRateLimitUnsupported{}) {
|
||||
if errors.HasType[extsvc.ErrRateLimitUnsupported](err) {
|
||||
continue
|
||||
}
|
||||
errs = errors.Append(errs, errors.Wrap(err, "getting rate limit configuration"))
|
||||
|
||||
@ -81,7 +81,7 @@ func shortenErrHelp(cmd *ffcli.Command, cmdPath string) {
|
||||
exec := cmd.Exec
|
||||
cmd.Exec = func(args []string) error {
|
||||
err := exec(args)
|
||||
if errors.HasType(err, &usageError{}) {
|
||||
if errors.HasType[*usageError](err) {
|
||||
var w io.Writer
|
||||
if cmd.FlagSet != nil {
|
||||
w = cmd.FlagSet.Output()
|
||||
|
||||
@ -330,7 +330,7 @@ func (e *executor) publishChangeset(ctx context.Context, asDraft bool) (afterDon
|
||||
|
||||
func (e *executor) syncChangeset(ctx context.Context) error {
|
||||
if err := e.loadChangeset(ctx); err != nil {
|
||||
if !errors.HasType(err, sources.ChangesetNotFoundError{}) {
|
||||
if !errors.HasType[sources.ChangesetNotFoundError](err) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -1647,7 +1647,7 @@ index e5af166..d44c3fc 100644
|
||||
|
||||
// Execute BatchSpec by creating execution jobs
|
||||
_, err := svc.ExecuteBatchSpec(adminCtx, ExecuteBatchSpecOpts{BatchSpecRandID: spec.RandID})
|
||||
if !errors.HasType(err, ErrBatchSpecResolutionErrored{}) {
|
||||
if !errors.HasType[ErrBatchSpecResolutionErrored](err) {
|
||||
t.Fatalf("error has wrong type: %T", err)
|
||||
}
|
||||
})
|
||||
@ -3412,7 +3412,7 @@ func assertAuthError(t *testing.T, err error) {
|
||||
if err == nil {
|
||||
t.Fatalf("expected error. got none")
|
||||
}
|
||||
if !errors.HasType(err, &auth.InsufficientAuthorizationError{}) {
|
||||
if !errors.HasType[*auth.InsufficientAuthorizationError](err) {
|
||||
t.Fatalf("wrong error: %s (%T)", err, err)
|
||||
}
|
||||
}
|
||||
@ -3424,7 +3424,7 @@ func assertOrgOrAuthError(t *testing.T, err error) {
|
||||
t.Fatal("expected org authorization error, got none")
|
||||
}
|
||||
|
||||
if !errors.HasType(err, auth.ErrNotAnOrgMember) && !errors.HasType(err, &auth.InsufficientAuthorizationError{}) {
|
||||
if !errors.Is(err, auth.ErrNotAnOrgMember) && !errors.HasType[*auth.InsufficientAuthorizationError](err) {
|
||||
t.Fatalf("expected authorization error, got %s", err.Error())
|
||||
}
|
||||
}
|
||||
@ -3433,7 +3433,7 @@ func assertNoAuthError(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
|
||||
// Ignore other errors, we only want to check whether it's an auth error
|
||||
if errors.HasType(err, &auth.InsufficientAuthorizationError{}) || errors.Is(err, auth.ErrNotAnOrgMember) {
|
||||
if errors.HasType[*auth.InsufficientAuthorizationError](err) || errors.Is(err, auth.ErrNotAnOrgMember) {
|
||||
t.Fatalf("got auth error")
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +299,7 @@ func (wr *workspaceResolver) resolveRepositoryNameAndBranch(ctx context.Context,
|
||||
commit, err := wr.gitserverClient.ResolveRevision(ctx, repo.Name, branch, gitserver.ResolveRevisionOptions{
|
||||
EnsureRevision: false,
|
||||
})
|
||||
if err != nil && errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if err != nil && errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, errors.Newf("no branch matching %q found for repository %s", branch, name)
|
||||
}
|
||||
|
||||
|
||||
@ -786,7 +786,7 @@ func TestBitbucketServerSource_WithAuthenticator(t *testing.T) {
|
||||
src, err := bbsSrc.WithAuthenticator(tc)
|
||||
if err == nil {
|
||||
t.Error("unexpected nil error")
|
||||
} else if !errors.HasType(err, UnsupportedAuthenticatorError{}) {
|
||||
} else if !errors.HasType[UnsupportedAuthenticatorError](err) {
|
||||
t.Errorf("unexpected error of type %T: %v", err, err)
|
||||
}
|
||||
if src != nil {
|
||||
|
||||
@ -1374,7 +1374,7 @@ func TestGitLabSource_WithAuthenticator(t *testing.T) {
|
||||
src, err = src.WithAuthenticator(tc)
|
||||
if err == nil {
|
||||
t.Error("unexpected nil error")
|
||||
} else if !errors.HasType(err, UnsupportedAuthenticatorError{}) {
|
||||
} else if !errors.HasType[UnsupportedAuthenticatorError](err) {
|
||||
t.Errorf("unexpected error of type %T: %v", err, err)
|
||||
}
|
||||
if src != nil {
|
||||
|
||||
@ -514,7 +514,7 @@ func (s *changesetSyncer) SyncChangeset(ctx context.Context, id int64) error {
|
||||
func SyncChangeset(ctx context.Context, syncStore SyncStore, client gitserver.Client, source sources.ChangesetSource, repo *types.Repo, c *btypes.Changeset) (err error) {
|
||||
repoChangeset := &sources.Changeset{TargetRepo: repo, Changeset: c}
|
||||
if err := source.LoadChangeset(ctx, repoChangeset); err != nil {
|
||||
if !errors.HasType(err, sources.ChangesetNotFoundError{}) {
|
||||
if !errors.HasType[sources.ChangesetNotFoundError](err) {
|
||||
// Store the error as the syncer error.
|
||||
errMsg := err.Error()
|
||||
c.SyncErrorMessage = &errMsg
|
||||
|
||||
@ -191,7 +191,7 @@ func (b indexSchedulerJob) handleRepository(ctx context.Context, repositoryID, p
|
||||
|
||||
// Attempt to queue an index if one does not exist for each of the matching commits
|
||||
if _, err := b.indexEnqueuer.QueueIndexes(ctx, repositoryID, commit, "", false, false); err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ func (s *Service) InferIndexConfiguration(ctx context.Context, repositoryID int,
|
||||
} else {
|
||||
// Verify that the commit exists.
|
||||
_, err := s.gitserverClient.GetCommit(ctx, repo.Name, api.CommitID(commit))
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, errors.Newf("revision %s not found for %d", commit, repositoryID)
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@ -147,7 +147,7 @@ func (c *commitCache) commitsExist(ctx context.Context, commits []RepositoryComm
|
||||
for i, rc := range repoCommits {
|
||||
_, err := c.gitserverClient.GetCommit(ctx, rc.repoName, rc.commitID)
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
exists[i] = false
|
||||
continue
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ func (m *Matcher) matchCommitPolicies(ctx context.Context, context matcherContex
|
||||
if policy.Type == shared.GitObjectTypeCommit {
|
||||
commit, err := m.gitserverClient.GetCommit(ctx, context.repo, api.CommitID(policy.Pattern))
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
|
||||
@ -60,7 +60,7 @@ func newCachedLocationResolver(
|
||||
resolveCommit := func(ctx context.Context, repositoryResolver resolverstubs.RepositoryResolver, commit string) (resolverstubs.GitCommitResolver, error) {
|
||||
commitID, err := gitserverClient.ResolveRevision(ctx, api.RepoName(repositoryResolver.Name()), commit, gitserver.ResolveRevisionOptions{EnsureRevision: false})
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
|
||||
@ -72,7 +72,7 @@ func (s *backfiller) BackfillCommittedAtBatch(ctx context.Context, batchSize int
|
||||
func (s *backfiller) getCommitDate(ctx context.Context, repositoryName, commitID string) (string, error) {
|
||||
commit, err := s.gitserverClient.GetCommit(ctx, api.RepoName(repositoryName), api.CommitID(commitID))
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
// Set a value here that we'll filter out on the query side so that we don't
|
||||
// reprocess the same failing batch infinitely. We could alternatively soft
|
||||
// delete the record, but it would be better to keep record deletion behavior
|
||||
|
||||
@ -73,7 +73,7 @@ func shouldDeleteRecordsForCommit(ctx context.Context, gitserverClient gitserver
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
// Repository is resolvable but commit is not - remove it
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ func (h *handler) HandleRawUpload(ctx context.Context, logger log.Logger, upload
|
||||
|
||||
commit, err := h.gitserverClient.GetCommit(ctx, repo.Name, api.CommitID(upload.Commit))
|
||||
if err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return errCommitDoesNotExist
|
||||
}
|
||||
return errors.Wrap(err, "failed to determine commit date")
|
||||
@ -415,7 +415,7 @@ func requeueIfCloningOrCommitUnknown(ctx context.Context, logger log.Logger, git
|
||||
}
|
||||
|
||||
var reason string
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
reason = "commit not found"
|
||||
} else if gitdomain.IsCloneInProgress(err) {
|
||||
reason = "repository still cloning"
|
||||
|
||||
@ -85,7 +85,7 @@ func ensureRepoAndCommitExist(ctx context.Context, repoStore RepoStore, repoName
|
||||
|
||||
if _, err := repoStore.ResolveRev(ctx, repo.Name, commit); err != nil {
|
||||
var reason string
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
reason = "commit not found"
|
||||
} else if gitdomain.IsCloneInProgress(err) {
|
||||
reason = "repository still cloning"
|
||||
|
||||
@ -1760,7 +1760,7 @@ func ensureCodeHost(ctx context.Context, tx *externalServiceStore, kind string,
|
||||
}
|
||||
// TODO: Use this method for the OOB migrator as well.
|
||||
rateLimit, isDefaultRateLimit, err := extsvc.ExtractRateLimit(config, kind)
|
||||
if err != nil && !errors.HasType(err, extsvc.ErrRateLimitUnsupported{}) {
|
||||
if err != nil && !errors.HasType[extsvc.ErrRateLimitUnsupported](err) {
|
||||
return 0, err
|
||||
}
|
||||
ch := &types.CodeHost{
|
||||
|
||||
@ -1433,7 +1433,7 @@ func TestExternalServiceStore_CancelSyncJob(t *testing.T) {
|
||||
|
||||
// Make sure "not found" is handled
|
||||
err = store.CancelSyncJob(ctx, ExternalServicesCancelSyncJobOptions{ID: 9999})
|
||||
if !errors.HasType(err, &errSyncJobNotFound{}) {
|
||||
if !errors.HasType[*errSyncJobNotFound](err) {
|
||||
t.Fatalf("Expected not-found error, have %q", err)
|
||||
}
|
||||
err = store.CancelSyncJob(ctx, ExternalServicesCancelSyncJobOptions{ExternalServiceID: 9999})
|
||||
@ -1504,7 +1504,7 @@ RETURNING id
|
||||
// Insert sync job in state that is not cancelable
|
||||
syncJobID4 := insertSyncJob(t, "completed")
|
||||
err = store.CancelSyncJob(ctx, ExternalServicesCancelSyncJobOptions{ID: syncJobID4})
|
||||
if !errors.HasType(err, &errSyncJobNotFound{}) {
|
||||
if !errors.HasType[*errSyncJobNotFound](err) {
|
||||
t.Fatalf("Expected not-found error, have %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ func TestOrgs_Delete(t *testing.T) {
|
||||
|
||||
// Org no longer exists.
|
||||
_, err = db.Orgs().GetByID(ctx, org.ID)
|
||||
if !errors.HasType(err, &OrgNotFoundError{}) {
|
||||
if !errors.HasType[*OrgNotFoundError](err) {
|
||||
t.Errorf("got error %v, want *OrgNotFoundError", err)
|
||||
}
|
||||
orgs, err := db.Orgs().List(ctx, &OrgsListOptions{Query: "a"})
|
||||
@ -142,7 +142,7 @@ func TestOrgs_Delete(t *testing.T) {
|
||||
|
||||
// Can't delete already-deleted org.
|
||||
err = db.Orgs().Delete(ctx, org.ID)
|
||||
if !errors.HasType(err, &OrgNotFoundError{}) {
|
||||
if !errors.HasType[*OrgNotFoundError](err) {
|
||||
t.Errorf("got error %v, want *OrgNotFoundError", err)
|
||||
}
|
||||
}
|
||||
@ -164,7 +164,7 @@ func TestOrgs_HardDelete(t *testing.T) {
|
||||
|
||||
// Org no longer exists.
|
||||
_, err = db.Orgs().GetByID(ctx, org.ID)
|
||||
if !errors.HasType(err, &OrgNotFoundError{}) {
|
||||
if !errors.HasType[*OrgNotFoundError](err) {
|
||||
t.Errorf("got error %v, want *OrgNotFoundError", err)
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ func TestOrgs_HardDelete(t *testing.T) {
|
||||
|
||||
// Cannot hard delete an org that doesn't exist.
|
||||
err = db.Orgs().HardDelete(ctx, org.ID)
|
||||
if !errors.HasType(err, &OrgNotFoundError{}) {
|
||||
if !errors.HasType[*OrgNotFoundError](err) {
|
||||
t.Errorf("got error %v, want *OrgNotFoundError", err)
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ func (s *phabricatorStore) CreateOrUpdate(ctx context.Context, callsign string,
|
||||
func (s *phabricatorStore) CreateIfNotExists(ctx context.Context, callsign string, name api.RepoName, phabURL string) (*types.PhabricatorRepo, error) {
|
||||
repo, err := s.GetByName(ctx, name)
|
||||
if err != nil {
|
||||
if !errors.HasType(err, errPhabricatorRepoNotFound{}) {
|
||||
if !errors.HasType[errPhabricatorRepoNotFound](err) {
|
||||
return nil, err
|
||||
}
|
||||
return s.Create(ctx, callsign, name, phabURL)
|
||||
|
||||
@ -233,7 +233,7 @@ func upsertRepo(ctx context.Context, db DB, op InsertRepoOp) error {
|
||||
// log_statement='mod'.
|
||||
r, err := s.GetByName(ctx, op.Name)
|
||||
if err != nil {
|
||||
if !errors.HasType(err, &RepoNotFoundErr{}) {
|
||||
if !errors.HasType[*RepoNotFoundErr](err) {
|
||||
return err
|
||||
}
|
||||
insert = true // missing
|
||||
|
||||
@ -154,7 +154,7 @@ func TestWebhookDelete(t *testing.T) {
|
||||
// Test that delete with wrong UUID returns an error
|
||||
nonExistentUUID := uuid.New()
|
||||
err := store.Delete(ctx, DeleteWebhookOpts{UUID: nonExistentUUID})
|
||||
if !errors.HasType(err, &WebhookNotFoundError{}) {
|
||||
if !errors.HasType[*WebhookNotFoundError](err) {
|
||||
t.Fatalf("want WebhookNotFoundError, got: %s", err)
|
||||
}
|
||||
assert.EqualError(t, err, fmt.Sprintf("failed to delete webhook: webhook with UUID %s not found", nonExistentUUID))
|
||||
@ -162,7 +162,7 @@ func TestWebhookDelete(t *testing.T) {
|
||||
// Test that delete with wrong ID returns an error
|
||||
nonExistentID := int32(123)
|
||||
err = store.Delete(ctx, DeleteWebhookOpts{ID: nonExistentID})
|
||||
if !errors.HasType(err, &WebhookNotFoundError{}) {
|
||||
if !errors.HasType[*WebhookNotFoundError](err) {
|
||||
t.Fatalf("want WebhookNotFoundError, got: %s", err)
|
||||
}
|
||||
assert.EqualError(t, err, fmt.Sprintf("failed to delete webhook: webhook with ID %d not found", nonExistentID))
|
||||
|
||||
@ -41,10 +41,10 @@ func HTTP(err error) int {
|
||||
return e.HTTPStatusCode()
|
||||
}
|
||||
|
||||
if errors.HasType(err, schema.ConversionError{}) {
|
||||
if errors.HasType[schema.ConversionError](err) {
|
||||
return http.StatusBadRequest
|
||||
}
|
||||
if errors.HasType(err, schema.MultiError{}) {
|
||||
if errors.HasType[schema.MultiError](err) {
|
||||
return http.StatusBadRequest
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ var ErrNotFound = errors.New("AWS CodeCommit repository not found")
|
||||
// IsNotFound reports whether err is a AWS CodeCommit API not-found error or the
|
||||
// equivalent cached response error.
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Is(err, ErrNotFound) || errors.HasType(err, &codecommittypes.RepositoryDoesNotExistException{})
|
||||
return errors.Is(err, ErrNotFound) || errors.HasType[*codecommittypes.RepositoryDoesNotExistException](err)
|
||||
}
|
||||
|
||||
// IsUnauthorized reports whether err is a AWS CodeCommit API unauthorized error.
|
||||
|
||||
@ -1658,7 +1658,7 @@ func (e OrgNotFoundError) NotFound() bool { return true }
|
||||
// IsNotFound reports whether err is a GitHub API error of type NOT_FOUND, the equivalent cached
|
||||
// response error, or HTTP 404.
|
||||
func IsNotFound(err error) bool {
|
||||
if errors.HasType(err, &RepoNotFoundError{}) || errors.HasType(err, &OrgNotFoundError{}) || errors.HasType(err, ErrPullRequestNotFound(0)) ||
|
||||
if errors.HasType[*RepoNotFoundError](err) || errors.HasType[*OrgNotFoundError](err) || errors.HasType[ErrPullRequestNotFound](err) ||
|
||||
HTTPErrorCode(err) == http.StatusNotFound {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -393,7 +393,7 @@ func HTTPErrorCode(err error) int {
|
||||
// IsNotFound reports whether err is a GitLab API error of type NOT_FOUND, the equivalent cached
|
||||
// response error, or HTTP 404.
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.HasType(err, &ProjectNotFoundError{}) ||
|
||||
return errors.HasType[*ProjectNotFoundError](err) ||
|
||||
errors.Is(err, ErrMergeRequestNotFound) ||
|
||||
HTTPErrorCode(err) == http.StatusNotFound
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ func (c *clientImplementor) Diff(ctx context.Context, repo api.RepoName, opts Di
|
||||
// We start by reading the first message to early-exit on potential errors.
|
||||
firstResp, firstRespErr := cc.Recv()
|
||||
if firstRespErr != nil {
|
||||
if errors.HasType(firstRespErr, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](firstRespErr) {
|
||||
cancel()
|
||||
err = firstRespErr
|
||||
endObservation(1, observation.Args{})
|
||||
@ -667,10 +667,10 @@ func (c *clientImplementor) GetDefaultBranch(ctx context.Context, repo api.RepoN
|
||||
})
|
||||
if err != nil {
|
||||
// If we fail to get the default branch due to cloning or being empty, we return nothing.
|
||||
if errors.HasType(err, &gitdomain.RepoNotExistError{}) {
|
||||
if errors.HasType[*gitdomain.RepoNotExistError](err) {
|
||||
return "", "", nil
|
||||
}
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return "", "", nil
|
||||
}
|
||||
return "", "", err
|
||||
@ -791,7 +791,7 @@ func (c *clientImplementor) NewFileReader(ctx context.Context, repo api.RepoName
|
||||
}
|
||||
}
|
||||
}
|
||||
if errors.HasType(firstRespErr, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](firstRespErr) {
|
||||
cancel()
|
||||
err = firstRespErr
|
||||
endObservation(1, observation.Args{})
|
||||
@ -1294,7 +1294,7 @@ func (c *clientImplementor) ArchiveReader(ctx context.Context, repo api.RepoName
|
||||
// ie. revision not found errors or invalid git command.
|
||||
firstMessage, firstErr := cli.Recv()
|
||||
if firstErr != nil {
|
||||
if errors.HasType(firstErr, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](firstErr) {
|
||||
cancel()
|
||||
err = firstErr
|
||||
endObservation(1, observation.Args{})
|
||||
|
||||
@ -247,7 +247,7 @@ func TestClient_StreamBlameFile(t *testing.T) {
|
||||
|
||||
_, err := c.StreamBlameFile(context.Background(), "repo", "file", &BlameOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
t.Run("file not found errors are returned early", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
@ -387,7 +387,7 @@ func TestClient_MergeBase(t *testing.T) {
|
||||
|
||||
_, err := c.MergeBase(context.Background(), "repo", "master", "b2")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ func TestClient_NewFileReader(t *testing.T) {
|
||||
|
||||
_, err := c.NewFileReader(context.Background(), "repo", "deadbeef", "file")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
t.Run("empty file", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
@ -565,7 +565,7 @@ func TestClient_GetCommit(t *testing.T) {
|
||||
ctx := actor.WithActor(context.Background(), actor.FromUser(1))
|
||||
_, err := c.GetCommit(ctx, "repo", "deadbeef")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
t.Run("checks for subrepo permissions some files visible", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
@ -610,7 +610,7 @@ func TestClient_GetCommit(t *testing.T) {
|
||||
|
||||
_, err := c.GetCommit(context.Background(), "repo", "deadbeef")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -676,7 +676,7 @@ func TestClient_ArchiveReader(t *testing.T) {
|
||||
|
||||
_, err := c.ArchiveReader(context.Background(), "repo", ArchiveOptions{Treeish: "deadbeef", Format: ArchiveFormatTar, Paths: []string{"file"}})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
t.Run("checks for subrepo permissions enabled on the repo", func(t *testing.T) {
|
||||
source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) {
|
||||
@ -804,7 +804,7 @@ index e5af166..d44c3fc 100644
|
||||
|
||||
_, err := c.Diff(context.Background(), "repo", DiffOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -848,11 +848,11 @@ func TestClient_ResolveRevision(t *testing.T) {
|
||||
// First request fails with revision error
|
||||
_, err := c.ResolveRevision(context.Background(), "repo", "HEAD", ResolveRevisionOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
// First request fails with clone error
|
||||
_, err = c.ResolveRevision(context.Background(), "repo", "HEAD", ResolveRevisionOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RepoNotExistError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RepoNotExistError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -908,7 +908,7 @@ func TestClient_RevAtTime(t *testing.T) {
|
||||
|
||||
_, _, err := c.RevAtTime(context.Background(), "repo", "HEAD", time.Now())
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -960,7 +960,7 @@ func TestClient_ListRefs(t *testing.T) {
|
||||
// Should fail with clone error
|
||||
_, err := c.ListRefs(context.Background(), "repo", ListRefsOpts{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RepoNotExistError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RepoNotExistError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1009,7 +1009,7 @@ func TestClient_ContributorCounts(t *testing.T) {
|
||||
|
||||
_, err := c.ContributorCount(context.Background(), "repo", ContributorOptions{})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1061,7 +1061,7 @@ func TestClient_FirstEverCommit(t *testing.T) {
|
||||
// Should fail with clone error
|
||||
_, err := c.FirstEverCommit(context.Background(), "repo")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RepoNotExistError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RepoNotExistError](err))
|
||||
})
|
||||
|
||||
t.Run("empty repository", func(t *testing.T) {
|
||||
@ -1080,7 +1080,7 @@ func TestClient_FirstEverCommit(t *testing.T) {
|
||||
// Should fail with RepositoryEmptyError
|
||||
_, err := c.FirstEverCommit(context.Background(), "repo")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1131,7 +1131,7 @@ func TestClient_GetBehindAhead(t *testing.T) {
|
||||
// Should fail with clone error
|
||||
_, err := c.BehindAhead(context.Background(), "repo", "left", "right")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RepoNotExistError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RepoNotExistError](err))
|
||||
})
|
||||
|
||||
t.Run("revision not found", func(t *testing.T) {
|
||||
@ -1150,7 +1150,7 @@ func TestClient_GetBehindAhead(t *testing.T) {
|
||||
// Should fail with RevisionNotFoundError
|
||||
_, err := c.BehindAhead(context.Background(), "repo", "left", "right")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1226,8 +1226,8 @@ func TestClient_ChangedFiles(t *testing.T) {
|
||||
|
||||
// Check to see if either the initial error or the error from the iterator is a RepoNotExistError
|
||||
require.True(t,
|
||||
errors.HasType(initialErr, &gitdomain.RepoNotExistError{}) ||
|
||||
errors.HasType(iterErr, &gitdomain.RepoNotExistError{}))
|
||||
errors.HasType[*gitdomain.RepoNotExistError](initialErr) ||
|
||||
errors.HasType[*gitdomain.RepoNotExistError](iterErr))
|
||||
})
|
||||
|
||||
t.Run("revision not found", func(t *testing.T) {
|
||||
@ -1256,8 +1256,8 @@ func TestClient_ChangedFiles(t *testing.T) {
|
||||
|
||||
// Check to see if either the initial error or the error from the iterator is a RevisionNotFoundError
|
||||
require.True(t,
|
||||
errors.HasType(initialErr, &gitdomain.RevisionNotFoundError{}) ||
|
||||
errors.HasType(iterErr, &gitdomain.RevisionNotFoundError{}))
|
||||
errors.HasType[*gitdomain.RevisionNotFoundError](initialErr) ||
|
||||
errors.HasType[*gitdomain.RevisionNotFoundError](iterErr))
|
||||
|
||||
})
|
||||
})
|
||||
@ -1431,7 +1431,7 @@ func TestClient_GetObject(t *testing.T) {
|
||||
|
||||
_, err := c.GetObject(context.Background(), "repo", "deadbeef")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RepoNotExistError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RepoNotExistError](err))
|
||||
})
|
||||
|
||||
t.Run("object not found", func(t *testing.T) {
|
||||
@ -1449,7 +1449,7 @@ func TestClient_GetObject(t *testing.T) {
|
||||
|
||||
_, err := c.GetObject(context.Background(), "repo", "deadbeef")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1496,7 +1496,7 @@ func TestClient_Stat(t *testing.T) {
|
||||
|
||||
_, err := c.Stat(context.Background(), "repo", "HEAD", "file")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("FileNotFound", func(t *testing.T) {
|
||||
@ -1660,7 +1660,7 @@ func TestClient_ReadDir(t *testing.T) {
|
||||
|
||||
_, err := c.ReadDir(context.Background(), "repo", "HEAD", "file", true)
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
|
||||
t.Run("FileNotFound", func(t *testing.T) {
|
||||
@ -1816,7 +1816,7 @@ func TestClient_Commits(t *testing.T) {
|
||||
|
||||
_, err := c.Commits(context.Background(), "repo", CommitsOptions{AllRefs: true})
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.HasType(err, &gitdomain.RevisionNotFoundError{}))
|
||||
require.True(t, errors.HasType[*gitdomain.RevisionNotFoundError](err))
|
||||
})
|
||||
})
|
||||
t.Run("subrepo permissions", func(t *testing.T) {
|
||||
|
||||
@ -63,7 +63,7 @@ func (e *RepoNotExistError) Error() string {
|
||||
|
||||
// IsRepoNotExist reports if err is a RepoNotExistError.
|
||||
func IsRepoNotExist(err error) bool {
|
||||
return errors.HasType(err, &RepoNotExistError{})
|
||||
return errors.HasType[*RepoNotExistError](err)
|
||||
}
|
||||
|
||||
// IsCloneInProgress reports if err is a RepoNotExistError which has a clone
|
||||
|
||||
@ -86,7 +86,7 @@ func newOperations(observationCtx *observation.Context) *operations {
|
||||
MetricLabelValues: []string{"ResolveRevision"},
|
||||
Metrics: redMetrics,
|
||||
ErrorFilter: func(err error) observation.ErrorFilterBehaviour {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return observation.EmitForMetrics
|
||||
}
|
||||
return observation.EmitForSentry
|
||||
|
||||
@ -241,7 +241,7 @@ func makeHistoricalSearchJobFunc(logger log.Logger, commitClient GitCommitClient
|
||||
if len(bctx.execution.Revision) == 0 {
|
||||
recentCommits, revErr := commitClient.RecentCommits(ctx, bctx.repoName, bctx.execution.RecordingTime, "")
|
||||
if revErr != nil {
|
||||
if errors.HasType(revErr, &gitdomain.RevisionNotFoundError{}) || gitdomain.IsRepoNotExist(revErr) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](revErr) || gitdomain.IsRepoNotExist(revErr) {
|
||||
return // no error - repo may not be cloned yet (or not even pushed to code host yet)
|
||||
}
|
||||
err = errors.Append(err, errors.Wrap(revErr, "FindNearestCommit"))
|
||||
|
||||
@ -191,7 +191,7 @@ type featureNotActivatedError struct{ errcode.PresentationError }
|
||||
// a feature (e.g., Enterprise Starter not including an Enterprise-only feature).
|
||||
func IsFeatureNotActivated(err error) bool {
|
||||
// Also check for the pointer type to guard against stupid mistakes.
|
||||
return errors.HasType(err, featureNotActivatedError{}) || errors.HasType(err, &featureNotActivatedError{})
|
||||
return errors.HasType[featureNotActivatedError](err) || errors.HasType[*featureNotActivatedError](err)
|
||||
}
|
||||
|
||||
// IsFeatureEnabledLenient reports whether the current license enables the given
|
||||
|
||||
@ -217,7 +217,7 @@ func (c *diskCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
|
||||
func mustRegisterOnce(c prometheus.Collector) {
|
||||
err := registerer.Register(c)
|
||||
if err != nil && !errors.HasType(err, prometheus.AlreadyRegisteredError{}) {
|
||||
if err != nil && !errors.HasType[prometheus.AlreadyRegisteredError](err) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func (i *InstrumentedLimiter) WaitN(ctx context.Context, n int) error {
|
||||
// For GlobalLimiter instances, we return a special error type for BlockAll,
|
||||
// since we don't want to make two preflight redis calls to check limit and burst
|
||||
// above. We map it back to ErrBlockAll here then.
|
||||
if err != nil && errors.HasType(err, AllBlockedError{}) {
|
||||
if err != nil && errors.HasType[AllBlockedError](err) {
|
||||
return ErrBlockAll
|
||||
}
|
||||
d := time.Since(start)
|
||||
|
||||
@ -223,7 +223,7 @@ func TestBitbucketServerSource_WithAuthenticator(t *testing.T) {
|
||||
src, err := bbsSrc.WithAuthenticator(tc)
|
||||
if err == nil {
|
||||
t.Error("unexpected nil error")
|
||||
} else if !errors.HasType(err, UnsupportedAuthenticatorError{}) {
|
||||
} else if !errors.HasType[UnsupportedAuthenticatorError](err) {
|
||||
t.Errorf("unexpected error of type %T: %v", err, err)
|
||||
}
|
||||
if src != nil {
|
||||
|
||||
@ -278,7 +278,7 @@ func TestGitLabSource_WithAuthenticator(t *testing.T) {
|
||||
src, err = src.(UserSource).WithAuthenticator(tc)
|
||||
if err == nil {
|
||||
t.Error("unexpected nil error")
|
||||
} else if !errors.HasType(err, UnsupportedAuthenticatorError{}) {
|
||||
} else if !errors.HasType[UnsupportedAuthenticatorError](err) {
|
||||
t.Errorf("unexpected error of type %T: %v", err, err)
|
||||
}
|
||||
if src != nil {
|
||||
|
||||
@ -84,7 +84,7 @@ func (q *QueryDescription) QueryString() string {
|
||||
|
||||
// AlertForQuery converts errors in the query to search alerts.
|
||||
func AlertForQuery(queryString string, err error) *Alert {
|
||||
if errors.HasType(err, &query.ExpectedOperand{}) {
|
||||
if errors.HasType[*query.ExpectedOperand](err) {
|
||||
return &Alert{
|
||||
PrometheusType: "unsupported_and_or_query",
|
||||
Title: "Unable To Process Query",
|
||||
|
||||
@ -241,7 +241,7 @@ func (o *Observer) errorToAlert(ctx context.Context, err error) (*search.Alert,
|
||||
lErr *ErrLuckyQueries
|
||||
)
|
||||
|
||||
if errors.HasType(err, authz.ErrStalePermissions{}) {
|
||||
if errors.HasType[authz.ErrStalePermissions](err) {
|
||||
return search.AlertForStalePermissions(), nil
|
||||
}
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ func (s searchQuery) Search(ctx context.Context, repoRev types.RepositoryRevisio
|
||||
// An empty repository we treat as success. When searching HEAD we haven't
|
||||
// yet validated the commit actually exists so we need to ignore at this
|
||||
// point. We should consider
|
||||
if repoRev.Revision == "HEAD" && errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if repoRev.Revision == "HEAD" && errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -231,6 +231,5 @@ func (s searchQuery) minimalRepo(ctx context.Context, repoID api.RepoID) (sgtype
|
||||
}
|
||||
|
||||
func isReposMissingError(err error) bool {
|
||||
var m repos.MissingRepoRevsError
|
||||
return errors.Is(err, repos.ErrNoResolvedRepos) || errors.HasType(err, &m)
|
||||
return errors.Is(err, repos.ErrNoResolvedRepos) || errors.HasType[*repos.MissingRepoRevsError](err)
|
||||
}
|
||||
|
||||
@ -1639,7 +1639,7 @@ func TestRepoSubsetTextSearch(t *testing.T) {
|
||||
endpoint.Static("test"),
|
||||
false,
|
||||
)
|
||||
if !errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
|
||||
if !errors.HasType[*gitdomain.RevisionNotFoundError](err) {
|
||||
t.Fatalf("searching non-existent rev expected to fail with RevisionNotFoundError got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1237,7 +1237,7 @@ func Parse(in string, searchType SearchType) ([]Node, error) {
|
||||
|
||||
nodes, err := parser.parseOr()
|
||||
if err != nil {
|
||||
if errors.HasType(err, &ExpectedOperand{}) {
|
||||
if errors.HasType[*ExpectedOperand](err) {
|
||||
// The query may be unbalanced or malformed as in "(" or
|
||||
// "x or" and expects an operand. Try harder to parse it.
|
||||
if nodes, err := parser.tryFallbackParser(in); err == nil {
|
||||
|
||||
@ -171,7 +171,7 @@ func HandleRepoSearchResult(repoID api.RepoID, revSpecs []string, limitHit, time
|
||||
} else {
|
||||
status |= RepoStatusMissing
|
||||
}
|
||||
} else if errors.HasType(searchErr, &gitdomain.RevisionNotFoundError{}) {
|
||||
} else if errors.HasType[*gitdomain.RevisionNotFoundError](searchErr) {
|
||||
if len(revSpecs) == 0 || len(revSpecs) == 1 && revSpecs[0] == "" {
|
||||
// If we didn't specify an input revision, then the repo is empty and can be ignored.
|
||||
} else {
|
||||
|
||||
@ -531,7 +531,7 @@ func (r *Resolver) normalizeRepoRefs(
|
||||
case rev.RevAtTime != nil:
|
||||
commitOID, found, err := r.gitserver.RevAtTime(ctx, repo.Name, rev.RevAtTime.RevSpec, rev.RevAtTime.Timestamp)
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType(err, &gitdomain.BadCommitError{}) {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType[*gitdomain.BadCommitError](err) {
|
||||
return nil, err
|
||||
}
|
||||
reportMissing(RepoRevSpecs{Repo: repo, Revs: []query.RevisionSpecifier{rev}})
|
||||
@ -550,7 +550,7 @@ func (r *Resolver) normalizeRepoRefs(
|
||||
trimmedRev := strings.TrimPrefix(rev.RevSpec, "^")
|
||||
_, err := r.gitserver.ResolveRevision(ctx, repo.Name, trimmedRev, gitserver.ResolveRevisionOptions{EnsureRevision: false})
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType(err, &gitdomain.BadCommitError{}) {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType[*gitdomain.BadCommitError](err) {
|
||||
return nil, err
|
||||
}
|
||||
reportMissing(RepoRevSpecs{Repo: repo, Revs: []query.RevisionSpecifier{rev}})
|
||||
@ -619,7 +619,7 @@ func (r *Resolver) filterHasCommitAfter(
|
||||
rev := rev
|
||||
p.Go(func(ctx context.Context) error {
|
||||
if hasCommitAfter, err := hasCommitAfter(ctx, r.gitserver, repoRev.Repo.Name, timeRef, rev); err != nil {
|
||||
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) || gitdomain.IsRepoNotExist(err) {
|
||||
if errors.HasType[*gitdomain.RevisionNotFoundError](err) || gitdomain.IsRepoNotExist(err) {
|
||||
// If the revision does not exist or the repo does not exist,
|
||||
// it certainly does not have any commits after some time.
|
||||
// Ignore the error, but filter this repo out.
|
||||
@ -815,7 +815,7 @@ func (r *Resolver) filterRepoHasFileContent(
|
||||
checkHasMatches := func(ctx context.Context, arg query.RepoHasFileContentArgs, repo types.MinimalRepo, rev string) (bool, error) {
|
||||
commitID, err := r.gitserver.ResolveRevision(ctx, repo.Name, rev, gitserver.ResolveRevisionOptions{EnsureRevision: false})
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType(err, &gitdomain.BadCommitError{}) {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.HasType[*gitdomain.BadCommitError](err) {
|
||||
return false, err
|
||||
} else if e := (&gitdomain.RevisionNotFoundError{}); errors.As(err, &e) && (rev == "HEAD" || rev == "") {
|
||||
// In the case that we can't find HEAD, that means there are no commits, which means
|
||||
|
||||
@ -398,7 +398,7 @@ func authenticateByCookie(logger log.Logger, db database.DB, r *http.Request, w
|
||||
|
||||
var info *sessionInfo
|
||||
if err := GetData(r, "actor", &info); err != nil {
|
||||
if errors.HasType(err, &net.OpError{}) {
|
||||
if errors.HasType[*net.OpError](err) {
|
||||
// If fetching session info failed because of a Redis error, return empty Context
|
||||
// without deleting the session cookie and throw an internal server error.
|
||||
// This prevents background requests made by off-screen tabs from signing
|
||||
|
||||
@ -366,7 +366,7 @@ func (s *s3Store) create(ctx context.Context) error {
|
||||
Bucket: aws.String(s.bucket),
|
||||
})
|
||||
|
||||
if errors.HasType(err, &s3types.BucketAlreadyExists{}) || errors.HasType(err, &s3types.BucketAlreadyOwnedByYou{}) {
|
||||
if errors.HasType[*s3types.BucketAlreadyExists](err) || errors.HasType[*s3types.BucketAlreadyOwnedByYou](err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -206,7 +206,7 @@ func (e BatchSpecValidationError) Error() string {
|
||||
}
|
||||
|
||||
func IsValidationError(err error) bool {
|
||||
return errors.HasType(err, &BatchSpecValidationError{})
|
||||
return errors.HasType[*BatchSpecValidationError](err)
|
||||
}
|
||||
|
||||
// SkippedStepsForRepo calculates the steps required to run on the given repo.
|
||||
|
||||
@ -62,7 +62,6 @@ var (
|
||||
// concrete type but with different data.
|
||||
Is = errors.Is
|
||||
IsAny = errors.IsAny
|
||||
HasType = errors.HasType
|
||||
Cause = errors.Cause
|
||||
Unwrap = errors.Unwrap
|
||||
UnwrapAll = errors.UnwrapAll
|
||||
@ -109,6 +108,21 @@ func AsInterface[I any](err error, target *I) bool {
|
||||
return errors.As(err, target)
|
||||
}
|
||||
|
||||
// HasType checks if the error tree err has a node of type T.
|
||||
//
|
||||
// CAVEAT: HasType is implemented via As. So strictly speaking, it is
|
||||
// possible that HasType returns true via some implementation of
|
||||
// `interface { As(target any) bool }` in the error tree that
|
||||
// doesn't actually check the type.
|
||||
func HasType[T error](err error) bool {
|
||||
// At the moment, the cockroachdb/errors package's implementation
|
||||
// of HasType does not correctly handle multi-errors, whereas As does,
|
||||
// so we implement HasType via As.
|
||||
// (See https://github.com/cockroachdb/errors/issues/145)
|
||||
var zero T
|
||||
return As(err, &zero)
|
||||
}
|
||||
|
||||
// Extend multiError to work with cockroachdb errors. Implement here to keep imports in
|
||||
// one place.
|
||||
|
||||
|
||||
@ -37,25 +37,23 @@ func TestInvariants(t *testing.T) {
|
||||
rapid.Just(error(¬TheErrorOfInterest{})),
|
||||
rapid.Just(error(payloadLessStructError{})),
|
||||
)).Draw(t, "err")
|
||||
// Is implies As for errors without data
|
||||
// Is implies HasType and As for errors without data
|
||||
if Is(err, payloadLessStructError{}) {
|
||||
// This can be false, see Counter-example 1
|
||||
//require.True(t, HasType(err, payloadLessStructError{}))
|
||||
require.True(t, HasType[payloadLessStructError](err))
|
||||
var check payloadLessStructError
|
||||
require.True(t, As(err, &check))
|
||||
}
|
||||
// HasType implies Is and As for errors without data
|
||||
if HasType(err, payloadLessStructError{}) {
|
||||
if HasType[payloadLessStructError](err) {
|
||||
require.True(t, Is(err, payloadLessStructError{}))
|
||||
var check payloadLessStructError
|
||||
require.True(t, As(err, &check))
|
||||
}
|
||||
var check payloadLessStructError
|
||||
// As implies Is for errors without data
|
||||
// As implies Is and HasType for errors without data
|
||||
if As(err, &check) {
|
||||
require.True(t, Is(err, payloadLessStructError{}))
|
||||
// This can be false, see Counter-example 2
|
||||
//require.True(t, HasType(err, payloadLessStructError{}))
|
||||
require.True(t, HasType[payloadLessStructError](err))
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -70,31 +68,24 @@ func TestInvariants(t *testing.T) {
|
||||
rapid.Just(error(errorWithOtherData)),
|
||||
)).Draw(t, "err")
|
||||
|
||||
// Is implies As for errors with data
|
||||
// Is implies HasType and As for errors with data
|
||||
if Is(err, errorOfInterest) {
|
||||
// This is false, see Counter-example 5
|
||||
// This is false, see Counter-example 2
|
||||
//require.False(t, Is(err, errorWithOtherData))
|
||||
require.False(t, Is(err, withPayloadStructError{}))
|
||||
// These can be false, see Counter-example 1
|
||||
//require.True(t, HasType(err, errorOfInterest))
|
||||
//require.True(t, HasType(err, errorWithOtherData))
|
||||
//require.True(t, HasType(err, withPayloadStructError{}))
|
||||
require.True(t, HasType[withPayloadStructError](err))
|
||||
var check withPayloadStructError
|
||||
require.True(t, As(err, &check))
|
||||
// This can be false, see Counter-example 6
|
||||
// This can be false, see Counter-example 3
|
||||
//require.Equal(t, errorOfInterest, check)
|
||||
}
|
||||
|
||||
// HasType implies As for errors with data
|
||||
if HasType(err, errorOfInterest) {
|
||||
require.True(t, HasType(err, errorWithOtherData))
|
||||
require.True(t, HasType(err, withPayloadStructError{}))
|
||||
// This can be false, see Counter-example 3
|
||||
if HasType[withPayloadStructError](err) {
|
||||
// This can be false, see Counter-example 1
|
||||
//require.True(t, Is(err, errorOfInterest))
|
||||
var check withPayloadStructError
|
||||
require.True(t, As(err, &check))
|
||||
// This can be false, see Counter-example 4
|
||||
//require.Equal(t, errorOfInterest, check)
|
||||
}
|
||||
|
||||
// As implies a limited form of Is for errors with data
|
||||
@ -102,10 +93,7 @@ func TestInvariants(t *testing.T) {
|
||||
if As(err, &check) {
|
||||
require.True(t, check == errorOfInterest || check == errorWithOtherData)
|
||||
require.True(t, Is(err, errorOfInterest) || Is(err, errorWithOtherData))
|
||||
// These can be false, see Counter-example 2
|
||||
//require.True(t, HasType(err, errorOfInterest))
|
||||
//require.True(t, HasType(err, errorWithOtherData))
|
||||
//require.True(t, HasType(err, withPayloadStructError{}))
|
||||
require.True(t, HasType[withPayloadStructError](err))
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -116,25 +104,23 @@ func TestInvariants(t *testing.T) {
|
||||
rapid.Just(error(¬TheErrorOfInterest{})),
|
||||
rapid.Just(error(&payloadLessPtrError{})),
|
||||
)).Draw(t, "err")
|
||||
// Is implies As for errors without data
|
||||
// Is implies HasType and As for errors without data
|
||||
if Is(err, &payloadLessPtrError{}) {
|
||||
// This can be false, see Counter-example 1
|
||||
//require.True(t, HasType(err, &payloadLessPtrError{}))
|
||||
require.True(t, HasType[*payloadLessPtrError](err))
|
||||
var check *payloadLessPtrError
|
||||
require.True(t, As(err, &check))
|
||||
}
|
||||
// HasType implies Is and As for errors without data
|
||||
if HasType(err, &payloadLessPtrError{}) {
|
||||
if HasType[*payloadLessPtrError](err) {
|
||||
require.True(t, Is(err, &payloadLessPtrError{}))
|
||||
var check *payloadLessPtrError
|
||||
require.True(t, As(err, &check))
|
||||
}
|
||||
var check *payloadLessPtrError
|
||||
// As implies Is for errors without data
|
||||
// As implies Is and HasType for errors without data
|
||||
if As(err, &check) {
|
||||
require.True(t, Is(err, &payloadLessPtrError{}))
|
||||
// This can be false, see Counter-example 2
|
||||
//require.True(t, errors.HasType(err, &payloadLessPtrError{}))
|
||||
require.True(t, HasType[*payloadLessPtrError](err))
|
||||
}
|
||||
})
|
||||
})
|
||||
@ -149,81 +135,51 @@ func TestInvariants(t *testing.T) {
|
||||
rapid.Just(error(errorWithOtherData)),
|
||||
)).Draw(t, "err")
|
||||
|
||||
// Is implies As for errors with data
|
||||
// Is implies HasType and As for errors with data
|
||||
if Is(err, errorOfInterest) {
|
||||
// This is false, see Counter-example 5
|
||||
// This is false, see Counter-example 2
|
||||
//require.False(t, Is(err, errorWithOtherData))
|
||||
require.False(t, Is(err, &withPayloadPtrError{}))
|
||||
// These can be false, see Counter-example 1
|
||||
//require.True(t, HasType(err, errorOfInterest))
|
||||
//require.True(t, HasType(err, errorWithOtherData))
|
||||
//require.True(t, HasType(err, withPayloadStructError{}))
|
||||
require.True(t, HasType[*withPayloadPtrError](err))
|
||||
var check *withPayloadPtrError
|
||||
require.True(t, As(err, &check))
|
||||
// This can be false, see Counter-example 6
|
||||
// This can be false, see Counter-example 3
|
||||
//require.Equal(t, *errorOfInterest, *check)
|
||||
}
|
||||
|
||||
// HasType implies As for errors with data
|
||||
if HasType(err, errorOfInterest) {
|
||||
require.True(t, HasType(err, errorWithOtherData))
|
||||
require.True(t, HasType(err, &withPayloadPtrError{}))
|
||||
//This can be false, see Counter-example 3
|
||||
if HasType[*withPayloadPtrError](err) {
|
||||
//This can be false, see Counter-example 1
|
||||
//require.True(t, Is(err, errorOfInterest))
|
||||
var check *withPayloadPtrError
|
||||
require.True(t, As(err, &check))
|
||||
require.True(t, *check == *errorOfInterest || *check == *errorWithOtherData)
|
||||
}
|
||||
|
||||
// As implies a limited form of Is for errors with data
|
||||
// As implies HasType and a limited form of Is for errors with data
|
||||
var check *withPayloadPtrError
|
||||
if As(err, &check) {
|
||||
require.True(t, *check == *errorOfInterest || *check == *errorWithOtherData)
|
||||
require.True(t, Is(err, errorOfInterest) || Is(err, errorWithOtherData))
|
||||
// These can be false, see Counter-example 2
|
||||
//require.True(t, HasType(err, errorOfInterest))
|
||||
//require.True(t, HasType(err, errorWithOtherData))
|
||||
require.True(t, HasType[*withPayloadPtrError](err))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Counter-examples", func(t *testing.T) {
|
||||
// Counter-example 1. Is does not imply HasType
|
||||
{
|
||||
err := Append(payloadLessStructError{}, ¬TheErrorOfInterest{})
|
||||
check := payloadLessStructError{}
|
||||
require.True(t, Is(err, check))
|
||||
require.False(t, HasType(err, check))
|
||||
}
|
||||
// Counter-example 2. As does not imply HasType
|
||||
{
|
||||
err := Append(payloadLessStructError{}, ¬TheErrorOfInterest{})
|
||||
check := payloadLessStructError{}
|
||||
require.True(t, As(err, &check))
|
||||
require.False(t, HasType(err, payloadLessStructError{}))
|
||||
}
|
||||
// Counter-example 3. HasType does not imply Is
|
||||
// Counter-example 1. HasType does not imply Is
|
||||
{
|
||||
err := error(withPayloadStructError{data: 3})
|
||||
require.True(t, HasType(err, withPayloadStructError{}))
|
||||
require.True(t, HasType[withPayloadStructError](err))
|
||||
require.False(t, Is(err, withPayloadStructError{data: 1}))
|
||||
}
|
||||
// Counter-example 4. HasType does not imply As
|
||||
{
|
||||
err := error(withPayloadStructError{data: 3})
|
||||
hasTypeCheck := withPayloadStructError{data: 1}
|
||||
require.True(t, HasType(err, hasTypeCheck))
|
||||
var valueFromAs withPayloadStructError
|
||||
require.True(t, As(err, &valueFromAs))
|
||||
require.NotEqual(t, hasTypeCheck, valueFromAs)
|
||||
}
|
||||
// Counter-example 5. Is can return true for distinct values
|
||||
// Counter-example 2. Is can return true for distinct values
|
||||
{
|
||||
err := Append(withPayloadStructError{data: 3}, withPayloadStructError{data: 1})
|
||||
require.True(t, Is(err, withPayloadStructError{data: 3}))
|
||||
require.True(t, Is(err, withPayloadStructError{data: 1}))
|
||||
}
|
||||
// Counter-example 6. As can return a different value than the one passed to Is
|
||||
// Counter-example 3. As can return a different value than the one passed to Is
|
||||
{
|
||||
err := Append(withPayloadStructError{data: 3}, withPayloadStructError{data: 1})
|
||||
var check withPayloadStructError
|
||||
|
||||
Loading…
Reference in New Issue
Block a user