From a6413f5d88f12466b3daa833668d0f59fc65ece4 Mon Sep 17 00:00:00 2001 From: Jason Chang Date: Wed, 26 Jul 2023 13:23:40 -0700 Subject: Update errors to extend BaseRepoError In order to better analyze and track repo errors, repo command failures need to be tied to specific errors in repo source code. Additionally a new GitCommandError was added to differentiate between general git related errors to failed git commands. Git commands that opt into verification will raise a GitCommandError if the command failed. The first step in this process is a general error refactoring Bug: b/293344017 Change-Id: I46944b1825ce892757c8dd3f7e2fab7e460760c0 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/380994 Commit-Queue: Jason Chang Reviewed-by: Aravind Vasudevan Tested-by: Jason Chang Reviewed-by: Joanna Wang --- git_command.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) (limited to 'git_command.py') diff --git a/git_command.py b/git_command.py index c7245ade..588a64fd 100644 --- a/git_command.py +++ b/git_command.py @@ -40,6 +40,10 @@ GIT_DIR = "GIT_DIR" LAST_GITDIR = None LAST_CWD = None +DEFAULT_GIT_FAIL_MESSAGE = "git command failure" +# Common line length limit +GIT_ERROR_STDOUT_LINES = 1 +GIT_ERROR_STDERR_LINES = 1 class _GitCall(object): @@ -237,6 +241,7 @@ class GitCommand(object): cwd=None, gitdir=None, objdir=None, + verify_command=False, ): if project: if not cwd: @@ -244,6 +249,10 @@ class GitCommand(object): if not gitdir: gitdir = project.gitdir + self.project = project + self.cmdv = cmdv + self.verify_command = verify_command + # Git on Windows wants its paths only using / for reliability. if platform_utils.isWindows(): if objdir: @@ -332,7 +341,11 @@ class GitCommand(object): stderr=stderr, ) except Exception as e: - raise GitError("%s: %s" % (command[1], e)) + raise GitCommandError( + message="%s: %s" % (command[1], e), + project=project.name if project else None, + command_args=cmdv, + ) if ssh_proxy: ssh_proxy.add_client(p) @@ -366,4 +379,61 @@ class GitCommand(object): return env def Wait(self): - return self.rc + if not self.verify_command or self.rc == 0: + return self.rc + + stdout = ( + "\n".join(self.stdout.split("\n")[:GIT_ERROR_STDOUT_LINES]) + if self.stdout + else None + ) + + stderr = ( + "\n".join(self.stderr.split("\n")[:GIT_ERROR_STDERR_LINES]) + if self.stderr + else None + ) + project = self.project.name if self.project else None + raise GitCommandError( + project=project, + command_args=self.cmdv, + git_rc=self.rc, + git_stdout=stdout, + git_stderr=stderr, + ) + + +class GitCommandError(GitError): + """ + Error raised from a failed git command. + Note that GitError can refer to any Git related error (e.g. branch not + specified for project.py 'UploadForReview'), while GitCommandError is + raised exclusively from non-zero exit codes returned from git commands. + """ + + def __init__( + self, + message: str = DEFAULT_GIT_FAIL_MESSAGE, + git_rc: int = None, + git_stdout: str = None, + git_stderr: str = None, + **kwargs, + ): + super().__init__( + message, + **kwargs, + ) + self.git_rc = git_rc + self.git_stdout = git_stdout + self.git_stderr = git_stderr + + def __str__(self): + args = "[]" if not self.command_args else " ".join(self.command_args) + error_type = type(self).__name__ + return f"""{error_type}: {self.message} + Project: {self.project} + Args: {args} + Stdout: +{self.git_stdout} + Stderr: +{self.git_stderr}""" -- cgit v1.2.3-54-g00ecf