Skip to content

Commit 99b5a17

Browse files
gavinmakLUCI
authored andcommitted
sync: Share final error handling logic between sync modes
Dedupe error reporting logic for phased and interleaved sync modes by extracting it into _ReportErrors. Error reporting will now distinguish between network and local failures and lists the specific repos that failed in each phase. Bug: 421935613 Change-Id: I4604a83943dbbd71d979158d7a1c4b8c243347d2 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/484541 Tested-by: Gavin Mak <[email protected]> Reviewed-by: Scott Lee <[email protected]> Commit-Queue: Gavin Mak <[email protected]>
1 parent df3c401 commit 99b5a17

File tree

1 file changed

+72
-27
lines changed

1 file changed

+72
-27
lines changed

subcmds/sync.py

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,46 @@ def _UpdateManifestLists(
20542054
raise SyncFailFastError(aggregate_errors=errors)
20552055
return err_update_projects, err_update_linkfiles
20562056

2057+
def _ReportErrors(
2058+
self,
2059+
errors,
2060+
err_network_sync=False,
2061+
failing_network_repos=None,
2062+
err_checkout=False,
2063+
failing_checkout_repos=None,
2064+
err_update_projects=False,
2065+
err_update_linkfiles=False,
2066+
):
2067+
"""Logs detailed error messages and raises a SyncError."""
2068+
2069+
def print_and_log(err_msg):
2070+
self.git_event_log.ErrorEvent(err_msg)
2071+
logger.error("%s", err_msg)
2072+
2073+
print_and_log("error: Unable to fully sync the tree")
2074+
if err_network_sync:
2075+
print_and_log("error: Downloading network changes failed.")
2076+
if failing_network_repos:
2077+
logger.error(
2078+
"Failing repos (network):\n%s",
2079+
"\n".join(sorted(failing_network_repos)),
2080+
)
2081+
if err_update_projects:
2082+
print_and_log("error: Updating local project lists failed.")
2083+
if err_update_linkfiles:
2084+
print_and_log("error: Updating copyfiles or linkfiles failed.")
2085+
if err_checkout:
2086+
print_and_log("error: Checking out local projects failed.")
2087+
if failing_checkout_repos:
2088+
logger.error(
2089+
"Failing repos (checkout):\n%s",
2090+
"\n".join(sorted(failing_checkout_repos)),
2091+
)
2092+
logger.error(
2093+
'Try re-running with "-j1 --fail-fast" to exit at the first error.'
2094+
)
2095+
raise SyncError(aggregate_errors=errors)
2096+
20572097
def _SyncPhased(
20582098
self,
20592099
opt,
@@ -2130,29 +2170,14 @@ def _SyncPhased(
21302170

21312171
# If we saw an error, exit with code 1 so that other scripts can check.
21322172
if err_event.is_set():
2133-
2134-
def print_and_log(err_msg):
2135-
self.git_event_log.ErrorEvent(err_msg)
2136-
logger.error("%s", err_msg)
2137-
2138-
print_and_log("error: Unable to fully sync the tree")
2139-
if err_network_sync:
2140-
print_and_log("error: Downloading network changes failed.")
2141-
if err_update_projects:
2142-
print_and_log("error: Updating local project lists failed.")
2143-
if err_update_linkfiles:
2144-
print_and_log("error: Updating copyfiles or linkfiles failed.")
2145-
if err_checkout:
2146-
print_and_log("error: Checking out local projects failed.")
2147-
if err_results:
2148-
# Don't log repositories, as it may contain sensitive info.
2149-
logger.error("Failing repos:\n%s", "\n".join(err_results))
2150-
# Not useful to log.
2151-
logger.error(
2152-
'Try re-running with "-j1 --fail-fast" to exit at the first '
2153-
"error."
2173+
self._ReportErrors(
2174+
errors,
2175+
err_network_sync=err_network_sync,
2176+
err_checkout=err_checkout,
2177+
failing_checkout_repos=err_results,
2178+
err_update_projects=err_update_projects,
2179+
err_update_linkfiles=err_update_linkfiles,
21542180
)
2155-
raise SyncError(aggregate_errors=errors)
21562181

21572182
@classmethod
21582183
def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
@@ -2375,8 +2400,16 @@ def _ProcessSyncInterleavedResults(
23752400
err_event.set()
23762401
if result.fetch_error:
23772402
errors.append(result.fetch_error)
2403+
self._interleaved_err_network = True
2404+
self._interleaved_err_network_results.append(
2405+
result.relpath
2406+
)
23782407
if result.checkout_error:
23792408
errors.append(result.checkout_error)
2409+
self._interleaved_err_checkout = True
2410+
self._interleaved_err_checkout_results.append(
2411+
result.relpath
2412+
)
23802413

23812414
if not ret and opt.fail_fast:
23822415
if pool:
@@ -2407,6 +2440,12 @@ def _SyncInterleaved(
24072440
2. Projects that share git objects are processed serially to prevent
24082441
race conditions.
24092442
"""
2443+
# Temporary state for tracking errors in interleaved mode.
2444+
self._interleaved_err_network = False
2445+
self._interleaved_err_network_results = []
2446+
self._interleaved_err_checkout = False
2447+
self._interleaved_err_checkout_results = []
2448+
24102449
err_event = multiprocessing.Event()
24112450
synced_relpaths = set()
24122451
project_list = list(all_projects)
@@ -2520,17 +2559,23 @@ def _SyncInterleaved(
25202559

25212560
pm.end()
25222561

2523-
self._UpdateManifestLists(opt, err_event, errors)
2562+
err_update_projects, err_update_linkfiles = self._UpdateManifestLists(
2563+
opt, err_event, errors
2564+
)
25242565
if not self.outer_client.manifest.IsArchive:
25252566
self._GCProjects(project_list, opt, err_event)
25262567

25272568
self._PrintManifestNotices(opt)
25282569
if err_event.is_set():
2529-
# TODO(b/421935613): Log errors better like SyncPhased.
2530-
logger.error(
2531-
"error: Unable to fully sync the tree in interleaved mode."
2570+
self._ReportErrors(
2571+
errors,
2572+
err_network_sync=self._interleaved_err_network,
2573+
failing_network_repos=self._interleaved_err_network_results,
2574+
err_checkout=self._interleaved_err_checkout,
2575+
failing_checkout_repos=self._interleaved_err_checkout_results,
2576+
err_update_projects=err_update_projects,
2577+
err_update_linkfiles=err_update_linkfiles,
25322578
)
2533-
raise SyncError(aggregate_errors=errors)
25342579

25352580

25362581
def _PostRepoUpgrade(manifest, quiet=False):

0 commit comments

Comments
 (0)