fix: [CODE-2501] Handle Internal Server Error When Querying Non-existing Git References (#3136)

BT-10437
Atefeh Mohseni Ejiyeh 2024-12-13 02:27:30 +00:00 committed by Harness
parent c7f7ade6b6
commit a6bb491688
7 changed files with 26 additions and 15 deletions

View File

@ -188,8 +188,10 @@ func (g *Git) listCommitSHAs(
} }
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
if err != nil { if cErr := command.AsError(err); cErr != nil {
// TODO: handle error in case they don't have a common merge base! if cErr.IsExitCode(128) && cErr.IsAmbiguousArgErr() {
return nil, errors.NotFound("reference %q is ambiguous", ref)
}
return nil, processGitErrorf(err, "failed to trigger rev-list command") return nil, processGitErrorf(err, "failed to trigger rev-list command")
} }
@ -563,7 +565,7 @@ func (g *Git) GetFullCommitID(
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
if err != nil { if err != nil {
if strings.Contains(err.Error(), "exit status 128") { if command.AsError(err).IsExitCode(128) {
return sha.None, errors.NotFound("commit not found %s", shortID) return sha.None, errors.NotFound("commit not found %s", shortID)
} }
return sha.None, err return sha.None, err

View File

@ -236,8 +236,8 @@ func (g *Git) GetRef(
) )
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
if err != nil { if cErr := command.AsError(err); cErr != nil {
if command.AsError(err).IsExitCode(128) && strings.Contains(err.Error(), "not a valid ref") { if cErr.IsExitCode(128) && cErr.IsInvalidRefErr() {
return sha.None, errors.NotFound("reference %q not found", ref) return sha.None, errors.NotFound("reference %q not found", ref)
} }
return sha.None, err return sha.None, err

View File

@ -18,7 +18,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"strings"
"github.com/harness/gitness/errors" "github.com/harness/gitness/errors"
"github.com/harness/gitness/git/command" "github.com/harness/gitness/git/command"
@ -33,7 +32,7 @@ func (g *Git) ResolveRev(ctx context.Context,
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(output))
if err != nil { if err != nil {
if strings.Contains(err.Error(), "ambiguous argument") { if command.AsError(err).IsAmbiguousArgErr() {
return sha.None, errors.InvalidArgument("could not resolve git revision: %s", rev) return sha.None, errors.InvalidArgument("could not resolve git revision: %s", rev)
} }
return sha.None, fmt.Errorf("failed to resolve git revision: %w", err) return sha.None, fmt.Errorf("failed to resolve git revision: %w", err)

View File

@ -18,6 +18,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os/exec" "os/exec"
"strings"
) )
var ( var (
@ -52,6 +53,14 @@ func (e *Error) IsExitCode(code int) bool {
return e.ExitCode() == code return e.ExitCode() == code
} }
func (e *Error) IsAmbiguousArgErr() bool {
return strings.Contains(e.Error(), "ambiguous argument")
}
func (e *Error) IsInvalidRefErr() bool {
return strings.Contains(e.Error(), "not a valid ref")
}
func (e *Error) Error() string { func (e *Error) Error() string {
if len(e.StdErr) != 0 { if len(e.StdErr) != 0 {
return fmt.Sprintf("%s: %s", e.Err.Error(), e.StdErr) return fmt.Sprintf("%s: %s", e.Err.Error(), e.StdErr)

View File

@ -290,8 +290,8 @@ func (u *RefUpdater) getRef(ctx context.Context) (sha.SHA, error) {
) )
output := &bytes.Buffer{} output := &bytes.Buffer{}
err := cmd.Run(ctx, command.WithDir(u.repoPath), command.WithStdout(output)) err := cmd.Run(ctx, command.WithDir(u.repoPath), command.WithStdout(output))
if err != nil { if cErr := command.AsError(err); cErr != nil {
if command.AsError(err).IsExitCode(128) && strings.Contains(err.Error(), "not a valid ref") { if cErr.IsExitCode(128) && cErr.IsInvalidRefErr() {
return sha.None, errors.NotFound("reference %q not found", u.ref) return sha.None, errors.NotFound("reference %q not found", u.ref)
} }
return sha.None, err return sha.None, err

View File

@ -48,14 +48,15 @@ func (s *Service) PushRemote(ctx context.Context, params *PushRemoteParams) erro
} }
repoPath := getFullPathForRepo(s.reposRoot, params.RepoUID) repoPath := getFullPathForRepo(s.reposRoot, params.RepoUID)
if ok, err := s.git.HasBranches(ctx, repoPath); ok { isEmpty, err := s.git.HasBranches(ctx, repoPath)
if err != nil { if err != nil {
return errors.Internal(err, "push to repo failed") return errors.Internal(err, "push to repo failed")
} }
if isEmpty {
return errors.InvalidArgument("cannot push empty repo") return errors.InvalidArgument("cannot push empty repo")
} }
err := s.git.Push(ctx, repoPath, api.PushOptions{ err = s.git.Push(ctx, repoPath, api.PushOptions{
Remote: params.RemoteURL, Remote: params.RemoteURL,
Force: false, Force: false,
Env: nil, Env: nil,

View File

@ -241,7 +241,7 @@ func (r *SharedRepo) GetTreeSHA(
command.WithStdout(stdout), command.WithStdout(stdout),
) )
if err != nil { if err != nil {
if strings.Contains(err.Error(), "ambiguous argument") { if command.AsError(err).IsAmbiguousArgErr() {
return sha.None, errors.NotFound("could not resolve git revision %q", rev) return sha.None, errors.NotFound("could not resolve git revision %q", rev)
} }
return sha.None, fmt.Errorf("failed to get tree sha: %w", err) return sha.None, fmt.Errorf("failed to get tree sha: %w", err)