diff options
author | Jason Chang <jasonnc@google.com> | 2023-07-14 16:45:35 -0700 |
---|---|---|
committer | LUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-08-02 18:29:05 +0000 |
commit | 32b59565b7bd41ec1a121869823557f0b2b022d7 (patch) | |
tree | 0cd0fe644ecc6e319df96861f26b77a55c9969eb /main.py | |
parent | a6413f5d88f12466b3daa833668d0f59fc65ece4 (diff) | |
download | git-repo-32b59565b7bd41ec1a121869823557f0b2b022d7.tar.gz |
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>
Diffstat (limited to 'main.py')
-rwxr-xr-x | main.py | 56 |
1 files changed, 47 insertions, 9 deletions
@@ -30,6 +30,7 @@ import sys | |||
30 | import textwrap | 30 | import textwrap |
31 | import time | 31 | import time |
32 | import urllib.request | 32 | import urllib.request |
33 | import json | ||
33 | 34 | ||
34 | try: | 35 | try: |
35 | import kerberos | 36 | import kerberos |
@@ -50,10 +51,12 @@ from editor import Editor | |||
50 | from error import DownloadError | 51 | from error import DownloadError |
51 | from error import InvalidProjectGroupsError | 52 | from error import InvalidProjectGroupsError |
52 | from error import ManifestInvalidRevisionError | 53 | from error import ManifestInvalidRevisionError |
53 | from error import ManifestParseError | ||
54 | from error import NoManifestException | 54 | from error import NoManifestException |
55 | from error import NoSuchProjectError | 55 | from error import NoSuchProjectError |
56 | from error import RepoChangedException | 56 | from error import RepoChangedException |
57 | from error import RepoExitError | ||
58 | from error import RepoUnhandledExceptionError | ||
59 | from error import RepoError | ||
57 | import gitc_utils | 60 | import gitc_utils |
58 | from manifest_xml import GitcClient, RepoClient | 61 | from manifest_xml import GitcClient, RepoClient |
59 | from pager import RunPager, TerminatePager | 62 | from pager import RunPager, TerminatePager |
@@ -97,6 +100,7 @@ else: | |||
97 | ) | 100 | ) |
98 | 101 | ||
99 | KEYBOARD_INTERRUPT_EXIT = 128 + signal.SIGINT | 102 | KEYBOARD_INTERRUPT_EXIT = 128 + signal.SIGINT |
103 | MAX_PRINT_ERRORS = 5 | ||
100 | 104 | ||
101 | global_options = optparse.OptionParser( | 105 | global_options = optparse.OptionParser( |
102 | usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]", | 106 | usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]", |
@@ -422,10 +426,33 @@ class _Repo(object): | |||
422 | """ | 426 | """ |
423 | try: | 427 | try: |
424 | execute_command_helper() | 428 | execute_command_helper() |
425 | except (KeyboardInterrupt, SystemExit, Exception) as e: | 429 | except ( |
430 | KeyboardInterrupt, | ||
431 | SystemExit, | ||
432 | Exception, | ||
433 | RepoExitError, | ||
434 | ) as e: | ||
426 | ok = isinstance(e, SystemExit) and not e.code | 435 | ok = isinstance(e, SystemExit) and not e.code |
436 | exception_name = type(e).__name__ | ||
437 | if isinstance(e, RepoUnhandledExceptionError): | ||
438 | exception_name = type(e.error).__name__ | ||
439 | if isinstance(e, RepoExitError): | ||
440 | aggregated_errors = e.aggregate_errors or [] | ||
441 | for error in aggregated_errors: | ||
442 | project = None | ||
443 | if isinstance(error, RepoError): | ||
444 | project = error.project | ||
445 | error_info = json.dumps( | ||
446 | { | ||
447 | "ErrorType": type(error).__name__, | ||
448 | "Project": project, | ||
449 | "Message": str(error), | ||
450 | } | ||
451 | ) | ||
452 | git_trace2_event_log.ErrorEvent( | ||
453 | f"AggregateExitError:{error_info}" | ||
454 | ) | ||
427 | if not ok: | 455 | if not ok: |
428 | exception_name = type(e).__name__ | ||
429 | git_trace2_event_log.ErrorEvent( | 456 | git_trace2_event_log.ErrorEvent( |
430 | f"RepoExitError:{exception_name}" | 457 | f"RepoExitError:{exception_name}" |
431 | ) | 458 | ) |
@@ -447,13 +474,13 @@ class _Repo(object): | |||
447 | "error: manifest missing or unreadable -- please run init", | 474 | "error: manifest missing or unreadable -- please run init", |
448 | file=sys.stderr, | 475 | file=sys.stderr, |
449 | ) | 476 | ) |
450 | result = 1 | 477 | result = e.exit_code |
451 | except NoSuchProjectError as e: | 478 | except NoSuchProjectError as e: |
452 | if e.name: | 479 | if e.name: |
453 | print("error: project %s not found" % e.name, file=sys.stderr) | 480 | print("error: project %s not found" % e.name, file=sys.stderr) |
454 | else: | 481 | else: |
455 | print("error: no project in current directory", file=sys.stderr) | 482 | print("error: no project in current directory", file=sys.stderr) |
456 | result = 1 | 483 | result = e.exit_code |
457 | except InvalidProjectGroupsError as e: | 484 | except InvalidProjectGroupsError as e: |
458 | if e.name: | 485 | if e.name: |
459 | print( | 486 | print( |
@@ -467,7 +494,7 @@ class _Repo(object): | |||
467 | "the current directory", | 494 | "the current directory", |
468 | file=sys.stderr, | 495 | file=sys.stderr, |
469 | ) | 496 | ) |
470 | result = 1 | 497 | result = e.exit_code |
471 | except SystemExit as e: | 498 | except SystemExit as e: |
472 | if e.code: | 499 | if e.code: |
473 | result = e.code | 500 | result = e.code |
@@ -475,6 +502,9 @@ class _Repo(object): | |||
475 | except KeyboardInterrupt: | 502 | except KeyboardInterrupt: |
476 | result = KEYBOARD_INTERRUPT_EXIT | 503 | result = KEYBOARD_INTERRUPT_EXIT |
477 | raise | 504 | raise |
505 | except RepoExitError as e: | ||
506 | result = e.exit_code | ||
507 | raise | ||
478 | except Exception: | 508 | except Exception: |
479 | result = 1 | 509 | result = 1 |
480 | raise | 510 | raise |
@@ -841,12 +871,20 @@ def _Main(argv): | |||
841 | SetTraceToStderr() | 871 | SetTraceToStderr() |
842 | 872 | ||
843 | result = repo._Run(name, gopts, argv) or 0 | 873 | result = repo._Run(name, gopts, argv) or 0 |
874 | except RepoExitError as e: | ||
875 | exception_name = type(e).__name__ | ||
876 | result = e.exit_code | ||
877 | print("fatal: %s" % e, file=sys.stderr) | ||
878 | if e.aggregate_errors: | ||
879 | print(f"{exception_name} Aggregate Errors") | ||
880 | for err in e.aggregate_errors[:MAX_PRINT_ERRORS]: | ||
881 | print(err) | ||
882 | if len(e.aggregate_errors) > MAX_PRINT_ERRORS: | ||
883 | diff = len(e.aggregate_errors) - MAX_PRINT_ERRORS | ||
884 | print(f"+{diff} additional errors ...") | ||
844 | except KeyboardInterrupt: | 885 | except KeyboardInterrupt: |
845 | print("aborted by user", file=sys.stderr) | 886 | print("aborted by user", file=sys.stderr) |
846 | result = KEYBOARD_INTERRUPT_EXIT | 887 | result = KEYBOARD_INTERRUPT_EXIT |
847 | except ManifestParseError as mpe: | ||
848 | print("fatal: %s" % mpe, file=sys.stderr) | ||
849 | result = 1 | ||
850 | except RepoChangedException as rce: | 888 | except RepoChangedException as rce: |
851 | # If repo changed, re-exec ourselves. | 889 | # If repo changed, re-exec ourselves. |
852 | # | 890 | # |