diff options
author | Jacob Vosmaer <jacob@gitlab.com> | 2018-12-19 14:51:03 +0300 |
---|---|---|
committer | Jacob Vosmaer <jacob@gitlab.com> | 2019-01-07 16:05:57 +0300 |
commit | 3c0a7e9595968ee3e9437d4215845a1dbc48c235 (patch) | |
tree | a5f19ea10a631da6f9c874607c90c1369309eb63 | |
parent | 41ead86cd16a5bb823175c8077d6a38c284dfe28 (diff) |
Simplify error wrapping in service/ref
-rw-r--r-- | changelogs/unreleased/simplify-error-handling.yml | 5 | ||||
-rw-r--r-- | internal/git/id.go | 17 | ||||
-rw-r--r-- | internal/helper/fieldextractors/fieldextractor.go | 10 | ||||
-rw-r--r-- | internal/service/ref/list_new_blobs.go | 42 | ||||
-rw-r--r-- | internal/service/ref/list_new_commits.go | 24 | ||||
-rw-r--r-- | internal/service/ref/list_new_commits_test.go | 40 | ||||
-rw-r--r-- | internal/service/ref/refexists.go | 28 | ||||
-rw-r--r-- | internal/service/ref/refname.go | 18 | ||||
-rw-r--r-- | internal/service/ref/refs.go | 70 | ||||
-rw-r--r-- | internal/service/ref/remote_branches.go | 13 | ||||
-rw-r--r-- | internal/service/ref/util.go | 5 |
11 files changed, 148 insertions, 124 deletions
diff --git a/changelogs/unreleased/simplify-error-handling.yml b/changelogs/unreleased/simplify-error-handling.yml new file mode 100644 index 000000000..c4e3119e4 --- /dev/null +++ b/changelogs/unreleased/simplify-error-handling.yml @@ -0,0 +1,5 @@ +--- +title: Simplify error wrapping in service/ref +merge_request: 1009 +author: +type: other diff --git a/internal/git/id.go b/internal/git/id.go new file mode 100644 index 000000000..f5fee4e54 --- /dev/null +++ b/internal/git/id.go @@ -0,0 +1,17 @@ +package git + +import ( + "fmt" + "regexp" +) + +var commitIDRegex = regexp.MustCompile(`\A[0-9a-f]{40}\z`) + +// ValidateCommitID checks if id could be a Git commit ID, syntactically. +func ValidateCommitID(id string) error { + if commitIDRegex.MatchString(id) { + return nil + } + + return fmt.Errorf("invalid commit ID: %q", id) +} diff --git a/internal/helper/fieldextractors/fieldextractor.go b/internal/helper/fieldextractors/fieldextractor.go index 141a38067..fa57328e8 100644 --- a/internal/helper/fieldextractors/fieldextractor.go +++ b/internal/helper/fieldextractors/fieldextractor.go @@ -78,15 +78,15 @@ func FieldExtractor(fullMethod string, req interface{}) map[string]interface{} { } var result map[string]interface{} - switch req.(type) { + switch req := req.(type) { case gitalypb.RenameNamespaceRequest: - result = formatRenameNamespaceRequest(req.(gitalypb.RenameNamespaceRequest)) + result = formatRenameNamespaceRequest(req) case repositoryBasedRequest: - result = formatRepoRequest(req.(repositoryBasedRequest).GetRepository()) + result = formatRepoRequest(req.GetRepository()) case namespaceBasedRequest: - result = formatNamespaceRequest(req.(namespaceBasedRequest)) + result = formatNamespaceRequest(req) case storageBasedRequest: - result = formatStorageRequest(req.(storageBasedRequest)) + result = formatStorageRequest(req) } if result == nil { diff --git a/internal/service/ref/list_new_blobs.go b/internal/service/ref/list_new_blobs.go index ff3dcd3a9..c22adb706 100644 --- a/internal/service/ref/list_new_blobs.go +++ b/internal/service/ref/list_new_blobs.go @@ -3,22 +3,28 @@ package ref import ( "bufio" "fmt" - "regexp" "strings" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/catfile" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/internal/helper" ) func (s *server) ListNewBlobs(in *gitalypb.ListNewBlobsRequest, stream gitalypb.RefService_ListNewBlobsServer) error { oid := in.GetCommitId() - if err := validateCommitID(oid); err != nil { - return err + if err := git.ValidateCommitID(oid); err != nil { + return helper.ErrInvalidArgument(err) + } + + if err := listNewBlobs(in, stream, oid); err != nil { + return helper.ErrInternal(err) } + return nil +} + +func listNewBlobs(in *gitalypb.ListNewBlobsRequest, stream gitalypb.RefService_ListNewBlobsServer, oid string) error { ctx := stream.Context() cmdArgs := []string{"rev-list", oid, "--objects", "--not", "--all"} @@ -28,15 +34,12 @@ func (s *server) ListNewBlobs(in *gitalypb.ListNewBlobsRequest, stream gitalypb. revList, err := git.Command(ctx, in.GetRepository(), cmdArgs...) if err != nil { - if _, ok := status.FromError(err); ok { - return err - } - return status.Errorf(codes.Internal, "ListNewBlobs: gitCommand: %v", err) + return err } batch, err := catfile.New(ctx, in.GetRepository()) if err != nil { - return status.Errorf(codes.Internal, "ListNewBlobs: catfile: %v", err) + return err } var newBlobs []*gitalypb.NewBlobObject @@ -51,7 +54,7 @@ func (s *server) ListNewBlobs(in *gitalypb.ListNewBlobsRequest, stream gitalypb. info, err := batch.Info(parts[0]) if err != nil { - return status.Errorf(codes.Internal, "ListNewBlobs: catfile: %v", err) + return err } if !info.IsBlob() { @@ -61,21 +64,18 @@ func (s *server) ListNewBlobs(in *gitalypb.ListNewBlobsRequest, stream gitalypb. newBlobs = append(newBlobs, &gitalypb.NewBlobObject{Oid: info.Oid, Size: info.Size, Path: []byte(parts[1])}) if len(newBlobs) >= 1000 { response := &gitalypb.ListNewBlobsResponse{NewBlobObjects: newBlobs} - stream.Send(response) + if err := stream.Send(response); err != nil { + return err + } + newBlobs = newBlobs[:0] } } response := &gitalypb.ListNewBlobsResponse{NewBlobObjects: newBlobs} - stream.Send(response) - - return revList.Wait() -} - -func validateCommitID(commitID string) error { - if match, err := regexp.MatchString(`\A[0-9a-f]{40}\z`, commitID); !match || err != nil { - return status.Errorf(codes.InvalidArgument, "commit id shoud have 40 hexidecimal characters") + if err := stream.Send(response); err != nil { + return err } - return nil + return revList.Wait() } diff --git a/internal/service/ref/list_new_commits.go b/internal/service/ref/list_new_commits.go index 4fb50c6f6..d7aea36e3 100644 --- a/internal/service/ref/list_new_commits.go +++ b/internal/service/ref/list_new_commits.go @@ -7,29 +7,33 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/catfile" "gitlab.com/gitlab-org/gitaly/internal/git/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/internal/helper" ) func (s *server) ListNewCommits(in *gitalypb.ListNewCommitsRequest, stream gitalypb.RefService_ListNewCommitsServer) error { oid := in.GetCommitId() - if err := validateCommitID(oid); err != nil { - return err + if err := git.ValidateCommitID(oid); err != nil { + return helper.ErrInvalidArgument(err) + } + + if err := listNewCommits(in, stream, oid); err != nil { + return helper.ErrInternal(err) } + return nil +} + +func listNewCommits(in *gitalypb.ListNewCommitsRequest, stream gitalypb.RefService_ListNewCommitsServer, oid string) error { ctx := stream.Context() revList, err := git.Command(ctx, in.GetRepository(), "rev-list", oid, "--not", "--all") if err != nil { - if _, ok := status.FromError(err); ok { - return err - } - return status.Errorf(codes.Internal, "ListNewCommits: gitCommand: %v", err) + return err } batch, err := catfile.New(ctx, in.GetRepository()) if err != nil { - return status.Errorf(codes.Internal, "ListNewCommits: catfile: %v", err) + return err } commits := []*gitalypb.GitCommit{} @@ -39,7 +43,7 @@ func (s *server) ListNewCommits(in *gitalypb.ListNewCommitsRequest, stream gital commit, err := log.GetCommitCatfile(batch, line) if err != nil { - return status.Errorf(codes.Internal, "ListNewCommits: commit not found: %v", err) + return err } commits = append(commits, commit) diff --git a/internal/service/ref/list_new_commits_test.go b/internal/service/ref/list_new_commits_test.go index 2bc13b3ab..abb513073 100644 --- a/internal/service/ref/list_new_commits_test.go +++ b/internal/service/ref/list_new_commits_test.go @@ -65,29 +65,31 @@ func TestListNewCommits(t *testing.T) { } for _, tc := range testCases { - request := &gitalypb.ListNewCommitsRequest{Repository: testRepo, CommitId: tc.revision} + t.Run(tc.revision, func(t *testing.T) { + request := &gitalypb.ListNewCommitsRequest{Repository: testRepo, CommitId: tc.revision} - stream, err := client.ListNewCommits(ctx, request) - require.NoError(t, err) + stream, err := client.ListNewCommits(ctx, request) + require.NoError(t, err) + + var commits []*gitalypb.GitCommit + for { + msg, err := stream.Recv() - var commits []*gitalypb.GitCommit - for { - msg, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + require.Equal(t, tc.responseCode, status.Code(err)) + break + } - if err == io.EOF { - break + require.NoError(t, err) + commits = append(commits, msg.Commits...) } - if err != nil { - require.Equal(t, tc.responseCode, status.Code(err)) - break + require.Len(t, commits, len(tc.newCommitOids)) + for i, commit := range commits { + require.Equal(t, commit.Id, tc.newCommitOids[i]) } - - require.NoError(t, err) - commits = append(commits, msg.Commits...) - } - require.Len(t, commits, len(tc.newCommitOids)) - for i, commit := range commits { - require.Equal(t, commit.Id, tc.newCommitOids[i]) - } + }) } } diff --git a/internal/service/ref/refexists.go b/internal/service/ref/refexists.go index e20248a62..e94ce97fa 100644 --- a/internal/service/ref/refexists.go +++ b/internal/service/ref/refexists.go @@ -1,44 +1,36 @@ package ref import ( + "fmt" "strings" - grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/git" + "gitlab.com/gitlab-org/gitaly/internal/helper" "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // RefExists returns true if the given reference exists. The ref must start with the string `ref/` func (server) RefExists(ctx context.Context, in *gitalypb.RefExistsRequest) (*gitalypb.RefExistsResponse, error) { ref := string(in.Ref) + + if !isValidRefName(ref) { + return nil, helper.ErrInvalidArgument(fmt.Errorf("invalid refname")) + } + exists, err := refExists(ctx, in.Repository, ref) if err != nil { - return nil, err + return nil, helper.ErrInternal(err) } return &gitalypb.RefExistsResponse{Value: exists}, nil } func refExists(ctx context.Context, repo *gitalypb.Repository, ref string) (bool, error) { - grpc_logrus.Extract(ctx).WithFields(log.Fields{ - "ref": ref, - }).Debug("refExists") - - if !isValidRefName(ref) { - return false, status.Errorf(codes.InvalidArgument, "invalid refname") - } - cmd, err := git.Command(ctx, repo, "show-ref", "--verify", "--quiet", ref) if err != nil { - if _, ok := status.FromError(err); ok { - return false, err - } - return false, status.Errorf(codes.Internal, err.Error()) + return false, err } err = cmd.Wait() @@ -53,7 +45,7 @@ func refExists(ctx context.Context, repo *gitalypb.Repository, ref string) (bool } // This will normally occur when exit code > 1 - return false, status.Errorf(codes.Internal, err.Error()) + return false, err } func isValidRefName(refName string) bool { diff --git a/internal/service/ref/refname.go b/internal/service/ref/refname.go index 518d5466c..ad6c488df 100644 --- a/internal/service/ref/refname.go +++ b/internal/service/ref/refname.go @@ -2,15 +2,13 @@ package ref import ( "bufio" + "fmt" "strings" - grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/git" + "gitlab.com/gitlab-org/gitaly/internal/helper" "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // FindRefName returns a ref that starts with the given prefix, if one exists. @@ -18,15 +16,12 @@ import ( // returned or that the same one is returned on each call. func (s *server) FindRefName(ctx context.Context, in *gitalypb.FindRefNameRequest) (*gitalypb.FindRefNameResponse, error) { if in.CommitId == "" { - return nil, status.Errorf(codes.InvalidArgument, "Bad Request (empty commit sha)") + return nil, helper.ErrInvalidArgument(fmt.Errorf("empty commit sha")) } ref, err := findRefName(ctx, in.Repository, in.CommitId, string(in.Prefix)) if err != nil { - if _, ok := status.FromError(err); ok { - return nil, err - } - return nil, status.Errorf(codes.Internal, err.Error()) + return nil, helper.ErrInternal(err) } return &gitalypb.FindRefNameResponse{Name: []byte(ref)}, nil @@ -34,11 +29,6 @@ func (s *server) FindRefName(ctx context.Context, in *gitalypb.FindRefNameReques // We assume `repo` and `commitID` and `prefix` are non-empty func findRefName(ctx context.Context, repo *gitalypb.Repository, commitID, prefix string) (string, error) { - grpc_logrus.Extract(ctx).WithFields(log.Fields{ - "commitSha": commitID, - "prefix": prefix, - }).Debug("findRefName") - cmd, err := git.Command(ctx, repo, "for-each-ref", "--format=%(refname)", "--count=1", prefix, "--contains", commitID) if err != nil { return "", err diff --git a/internal/service/ref/refs.go b/internal/service/ref/refs.go index e986e0ede..dadf91457 100644 --- a/internal/service/ref/refs.go +++ b/internal/service/ref/refs.go @@ -4,19 +4,15 @@ import ( "bufio" "bytes" "fmt" - "regexp" "strings" - grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" - log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/internal/helper/lines" "gitlab.com/gitlab-org/gitaly/internal/rubyserver" "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var ( @@ -34,10 +30,6 @@ type findRefsOpts struct { } func findRefs(ctx context.Context, writer lines.Sender, repo *gitalypb.Repository, patterns []string, opts *findRefsOpts) error { - grpc_logrus.Extract(ctx).WithFields(log.Fields{ - "Patterns": patterns, - }).Debug("FindRefs") - baseArgs := []string{"for-each-ref"} var args []string @@ -193,14 +185,9 @@ func DefaultBranchName(ctx context.Context, repo *gitalypb.Repository) ([]byte, // FindDefaultBranchName returns the default branch name for the given repository func (s *server) FindDefaultBranchName(ctx context.Context, in *gitalypb.FindDefaultBranchNameRequest) (*gitalypb.FindDefaultBranchNameResponse, error) { - grpc_logrus.Extract(ctx).Debug("FindDefaultBranchName") - defaultBranchName, err := DefaultBranchName(ctx, in.Repository) if err != nil { - if _, ok := status.FromError(err); ok { - return nil, err - } - return nil, status.Errorf(codes.Internal, err.Error()) + return nil, helper.ErrInternal(err) } return &gitalypb.FindDefaultBranchNameResponse{Name: defaultBranchName}, nil @@ -221,6 +208,14 @@ func parseSortKey(sortKey gitalypb.FindLocalBranchesRequest_SortBy) string { // FindLocalBranches creates a stream of branches for all local branches in the given repository func (s *server) FindLocalBranches(in *gitalypb.FindLocalBranchesRequest, stream gitalypb.RefService_FindLocalBranchesServer) error { + if err := findLocalBranches(in, stream); err != nil { + return helper.ErrInternal(err) + } + + return nil +} + +func findLocalBranches(in *gitalypb.FindLocalBranchesRequest, stream gitalypb.RefService_FindLocalBranchesServer) error { ctx := stream.Context() c, err := catfile.New(ctx, in.Repository) if err != nil { @@ -240,6 +235,14 @@ func (s *server) FindLocalBranches(in *gitalypb.FindLocalBranchesRequest, stream } func (s *server) FindAllBranches(in *gitalypb.FindAllBranchesRequest, stream gitalypb.RefService_FindAllBranchesServer) error { + if err := findAllBranches(in, stream); err != nil { + return helper.ErrInternal(err) + } + + return nil +} + +func findAllBranches(in *gitalypb.FindAllBranchesRequest, stream gitalypb.RefService_FindAllBranchesServer) error { args := []string{ // %00 inserts the null character into the output (see for-each-ref docs) "--format=" + strings.Join(localBranchFormatFields, "%00"), @@ -250,10 +253,7 @@ func (s *server) FindAllBranches(in *gitalypb.FindAllBranchesRequest, stream git if in.MergedOnly { defaultBranchName, err := DefaultBranchName(stream.Context(), in.Repository) if err != nil { - if _, ok := status.FromError(err); ok { - return err - } - return status.Errorf(codes.Internal, err.Error()) + return err } args = append(args, fmt.Sprintf("--merged=%s", string(defaultBranchName))) @@ -284,10 +284,18 @@ func (s *server) FindAllBranches(in *gitalypb.FindAllBranchesRequest, stream git // ListBranchNamesContainingCommit returns a maximum of in.GetLimit() Branch names // which contain the SHA1 passed as argument func (*server) ListBranchNamesContainingCommit(in *gitalypb.ListBranchNamesContainingCommitRequest, stream gitalypb.RefService_ListBranchNamesContainingCommitServer) error { - if !validCommitID(in.GetCommitId()) { - return status.Errorf(codes.InvalidArgument, "commit id was not a 40 character hexidecimal") + if err := git.ValidateCommitID(in.GetCommitId()); err != nil { + return helper.ErrInvalidArgument(err) } + if err := listBranchNamesContainingCommit(in, stream); err != nil { + return helper.ErrInternal(err) + } + + return nil +} + +func listBranchNamesContainingCommit(in *gitalypb.ListBranchNamesContainingCommitRequest, stream gitalypb.RefService_ListBranchNamesContainingCommitServer) error { args := []string{fmt.Sprintf("--contains=%s", in.GetCommitId()), "--format=%(refname:strip=2)"} if in.GetLimit() != 0 { args = append(args, fmt.Sprintf("--count=%d", in.GetLimit())) @@ -307,10 +315,18 @@ func (*server) ListBranchNamesContainingCommit(in *gitalypb.ListBranchNamesConta // ListTagNamesContainingCommit returns a maximum of in.GetLimit() Tag names // which contain the SHA1 passed as argument func (*server) ListTagNamesContainingCommit(in *gitalypb.ListTagNamesContainingCommitRequest, stream gitalypb.RefService_ListTagNamesContainingCommitServer) error { - if !validCommitID(in.GetCommitId()) { - return status.Errorf(codes.InvalidArgument, "commit id was not a 40 character hexidecimal") + if err := git.ValidateCommitID(in.GetCommitId()); err != nil { + return helper.ErrInvalidArgument(err) + } + + if err := listTagNamesContainingCommit(in, stream); err != nil { + return helper.ErrInternal(err) } + return nil +} + +func listTagNamesContainingCommit(in *gitalypb.ListTagNamesContainingCommitRequest, stream gitalypb.RefService_ListTagNamesContainingCommitServer) error { args := []string{fmt.Sprintf("--contains=%s", in.GetCommitId()), "--format=%(refname:strip=2)"} if in.GetLimit() != 0 { args = append(args, fmt.Sprintf("--count=%d", in.GetLimit())) @@ -326,11 +342,3 @@ func (*server) ListTagNamesContainingCommit(in *gitalypb.ListTagNamesContainingC delim: []byte("\n"), }) } - -func validCommitID(id string) bool { - if match, err := regexp.MatchString(`\A[0-9a-f]{40}\z`, id); !match || err != nil { - return false - } - - return true -} diff --git a/internal/service/ref/remote_branches.go b/internal/service/ref/remote_branches.go index ef582663b..4f8148ad3 100644 --- a/internal/service/ref/remote_branches.go +++ b/internal/service/ref/remote_branches.go @@ -6,15 +6,22 @@ import ( "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/git/catfile" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + "gitlab.com/gitlab-org/gitaly/internal/helper" ) func (s *server) FindAllRemoteBranches(req *gitalypb.FindAllRemoteBranchesRequest, stream gitalypb.RefService_FindAllRemoteBranchesServer) error { if err := validateFindAllRemoteBranchesRequest(req); err != nil { - return status.Errorf(codes.InvalidArgument, "FindAllRemoteBranches: %v", err) + return helper.ErrInvalidArgument(err) } + if err := findAllRemoteBranches(req, stream); err != nil { + return helper.ErrInternal(err) + } + + return nil +} + +func findAllRemoteBranches(req *gitalypb.FindAllRemoteBranchesRequest, stream gitalypb.RefService_FindAllRemoteBranchesServer) error { args := []string{ "--format=" + strings.Join(localBranchFormatFields, "%00"), } diff --git a/internal/service/ref/util.go b/internal/service/ref/util.go index f40221d47..978d3b914 100644 --- a/internal/service/ref/util.go +++ b/internal/service/ref/util.go @@ -2,13 +2,12 @@ package ref import ( "bytes" + "fmt" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/git/catfile" "gitlab.com/gitlab-org/gitaly/internal/git/log" "gitlab.com/gitlab-org/gitaly/internal/helper/lines" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var localBranchFormatFields = []string{"%(refname)", "%(objectname)"} @@ -16,7 +15,7 @@ var localBranchFormatFields = []string{"%(refname)", "%(objectname)"} func parseRef(ref []byte) ([][]byte, error) { elements := bytes.Split(ref, []byte("\x00")) if len(elements) != len(localBranchFormatFields) { - return nil, status.Errorf(codes.Internal, "error parsing ref %q", ref) + return nil, fmt.Errorf("error parsing ref %q", ref) } return elements, nil } |