Refactor errors for sync command

Per discussion in go/repo-error-update updated aggregated and exit
errors for sync command.

Aggregated errors are errors that result in eventual command failure.
Exit errors are errors that result in immediate command failure.

Also updated main.py to log aggregated and exit errors to git sessions
log

Bug: b/293344017
Change-Id: I77a21f14da32fe2e68c16841feb22de72e86a251
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/379614
Reviewed-by: Aravind Vasudevan <aravindvasudev@google.com>
Tested-by: Jason Chang <jasonnc@google.com>
Commit-Queue: Jason Chang <jasonnc@google.com>
This commit is contained in:
Jason Chang
2023-07-14 16:45:35 -07:00
committed by LUCI
parent a6413f5d88
commit 32b59565b7
5 changed files with 442 additions and 143 deletions

56
main.py
View File

@ -30,6 +30,7 @@ import sys
import textwrap
import time
import urllib.request
import json
try:
import kerberos
@ -50,10 +51,12 @@ from editor import Editor
from error import DownloadError
from error import InvalidProjectGroupsError
from error import ManifestInvalidRevisionError
from error import ManifestParseError
from error import NoManifestException
from error import NoSuchProjectError
from error import RepoChangedException
from error import RepoExitError
from error import RepoUnhandledExceptionError
from error import RepoError
import gitc_utils
from manifest_xml import GitcClient, RepoClient
from pager import RunPager, TerminatePager
@ -97,6 +100,7 @@ else:
)
KEYBOARD_INTERRUPT_EXIT = 128 + signal.SIGINT
MAX_PRINT_ERRORS = 5
global_options = optparse.OptionParser(
usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]",
@ -422,10 +426,33 @@ class _Repo(object):
"""
try:
execute_command_helper()
except (KeyboardInterrupt, SystemExit, Exception) as e:
except (
KeyboardInterrupt,
SystemExit,
Exception,
RepoExitError,
) as e:
ok = isinstance(e, SystemExit) and not e.code
exception_name = type(e).__name__
if isinstance(e, RepoUnhandledExceptionError):
exception_name = type(e.error).__name__
if isinstance(e, RepoExitError):
aggregated_errors = e.aggregate_errors or []
for error in aggregated_errors:
project = None
if isinstance(error, RepoError):
project = error.project
error_info = json.dumps(
{
"ErrorType": type(error).__name__,
"Project": project,
"Message": str(error),
}
)
git_trace2_event_log.ErrorEvent(
f"AggregateExitError:{error_info}"
)
if not ok:
exception_name = type(e).__name__
git_trace2_event_log.ErrorEvent(
f"RepoExitError:{exception_name}"
)
@ -447,13 +474,13 @@ class _Repo(object):
"error: manifest missing or unreadable -- please run init",
file=sys.stderr,
)
result = 1
result = e.exit_code
except NoSuchProjectError as e:
if e.name:
print("error: project %s not found" % e.name, file=sys.stderr)
else:
print("error: no project in current directory", file=sys.stderr)
result = 1
result = e.exit_code
except InvalidProjectGroupsError as e:
if e.name:
print(
@ -467,7 +494,7 @@ class _Repo(object):
"the current directory",
file=sys.stderr,
)
result = 1
result = e.exit_code
except SystemExit as e:
if e.code:
result = e.code
@ -475,6 +502,9 @@ class _Repo(object):
except KeyboardInterrupt:
result = KEYBOARD_INTERRUPT_EXIT
raise
except RepoExitError as e:
result = e.exit_code
raise
except Exception:
result = 1
raise
@ -841,12 +871,20 @@ def _Main(argv):
SetTraceToStderr()
result = repo._Run(name, gopts, argv) or 0
except RepoExitError as e:
exception_name = type(e).__name__
result = e.exit_code
print("fatal: %s" % e, file=sys.stderr)
if e.aggregate_errors:
print(f"{exception_name} Aggregate Errors")
for err in e.aggregate_errors[:MAX_PRINT_ERRORS]:
print(err)
if len(e.aggregate_errors) > MAX_PRINT_ERRORS:
diff = len(e.aggregate_errors) - MAX_PRINT_ERRORS
print(f"+{diff} additional errors ...")
except KeyboardInterrupt:
print("aborted by user", file=sys.stderr)
result = KEYBOARD_INTERRUPT_EXIT
except ManifestParseError as mpe:
print("fatal: %s" % mpe, file=sys.stderr)
result = 1
except RepoChangedException as rce:
# If repo changed, re-exec ourselves.
#