Skip to content

Commit d534a55

Browse files
gavinmakLUCI
authored andcommitted
sync: Fix missing error details in interleaved summary
When checkout errors occurred in interleaved sync, they were wrapped in a SyncError with no message, causing blank lines in the final summary. Refactor _SyncResult to hold a list of exceptions, ensuring the original error messages are propagated correctly. Bug: 438178765 Change-Id: Ic25e515068959829cb6290cfd9e4c2d3963bbbea Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/498342 Reviewed-by: Scott Lee <[email protected]> Tested-by: Gavin Mak <[email protected]> Commit-Queue: Gavin Mak <[email protected]>
1 parent a64149a commit d534a55

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

subcmds/sync.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,13 @@ class _SyncResult(NamedTuple):
204204
relpath (str): The project's relative path from the repo client top.
205205
remote_fetched (bool): True if the remote was actually queried.
206206
fetch_success (bool): True if the fetch operation was successful.
207-
fetch_error (Optional[Exception]): The Exception from a failed fetch,
208-
or None.
207+
fetch_errors (List[Exception]): The Exceptions from a failed fetch.
209208
fetch_start (Optional[float]): The time.time() when fetch started.
210209
fetch_finish (Optional[float]): The time.time() when fetch finished.
211210
checkout_success (bool): True if the checkout operation was
212211
successful.
213-
checkout_error (Optional[Exception]): The Exception from a failed
214-
checkout, or None.
212+
checkout_errors (List[Exception]): The Exceptions from a failed
213+
checkout.
215214
checkout_start (Optional[float]): The time.time() when checkout
216215
started.
217216
checkout_finish (Optional[float]): The time.time() when checkout
@@ -224,12 +223,12 @@ class _SyncResult(NamedTuple):
224223

225224
remote_fetched: bool
226225
fetch_success: bool
227-
fetch_error: Optional[Exception]
226+
fetch_errors: List[Exception]
228227
fetch_start: Optional[float]
229228
fetch_finish: Optional[float]
230229

231230
checkout_success: bool
232-
checkout_error: Optional[Exception]
231+
checkout_errors: List[Exception]
233232
checkout_start: Optional[float]
234233
checkout_finish: Optional[float]
235234

@@ -2210,7 +2209,7 @@ def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
22102209
"""Syncs a single project for interleaved sync."""
22112210
fetch_success = False
22122211
remote_fetched = False
2213-
fetch_error = None
2212+
fetch_errors = []
22142213
fetch_start = None
22152214
fetch_finish = None
22162215
network_output = ""
@@ -2243,16 +2242,17 @@ def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
22432242
)
22442243
fetch_success = sync_result.success
22452244
remote_fetched = sync_result.remote_fetched
2246-
fetch_error = sync_result.error
2245+
if sync_result.error:
2246+
fetch_errors.append(sync_result.error)
22472247
except KeyboardInterrupt:
22482248
logger.error(
22492249
"Keyboard interrupt while processing %s", project.name
22502250
)
22512251
except GitError as e:
2252-
fetch_error = e
2252+
fetch_errors.append(e)
22532253
logger.error("error.GitError: Cannot fetch %s", e)
22542254
except Exception as e:
2255-
fetch_error = e
2255+
fetch_errors.append(e)
22562256
logger.error(
22572257
"error: Cannot fetch %s (%s: %s)",
22582258
project.name,
@@ -2264,7 +2264,7 @@ def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
22642264
network_output = network_output_capture.getvalue()
22652265

22662266
checkout_success = False
2267-
checkout_error = None
2267+
checkout_errors = []
22682268
checkout_start = None
22692269
checkout_finish = None
22702270
checkout_stderr = ""
@@ -2293,22 +2293,20 @@ def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
22932293
)
22942294
checkout_success = syncbuf.Finish()
22952295
if syncbuf.errors:
2296-
checkout_error = SyncError(
2297-
aggregate_errors=syncbuf.errors
2298-
)
2296+
checkout_errors.extend(syncbuf.errors)
22992297
except KeyboardInterrupt:
23002298
logger.error(
23012299
"Keyboard interrupt while processing %s", project.name
23022300
)
23032301
except GitError as e:
2304-
checkout_error = e
2302+
checkout_errors.append(e)
23052303
logger.error(
23062304
"error.GitError: Cannot checkout %s: %s",
23072305
project.name,
23082306
e,
23092307
)
23102308
except Exception as e:
2311-
checkout_error = e
2309+
checkout_errors.append(e)
23122310
logger.error(
23132311
"error: Cannot checkout %s: %s: %s",
23142312
project.name,
@@ -2333,8 +2331,8 @@ def _SyncOneProject(cls, opt, project_index, project) -> _SyncResult:
23332331
fetch_success=fetch_success,
23342332
remote_fetched=remote_fetched,
23352333
checkout_success=checkout_success,
2336-
fetch_error=fetch_error,
2337-
checkout_error=checkout_error,
2334+
fetch_errors=fetch_errors,
2335+
checkout_errors=checkout_errors,
23382336
stderr_text=stderr_text.strip(),
23392337
fetch_start=fetch_start,
23402338
fetch_finish=fetch_finish,
@@ -2429,14 +2427,14 @@ def _ProcessSyncInterleavedResults(
24292427
if not success:
24302428
ret = False
24312429
err_event.set()
2432-
if result.fetch_error:
2433-
errors.append(result.fetch_error)
2430+
if result.fetch_errors:
2431+
errors.extend(result.fetch_errors)
24342432
self._interleaved_err_network = True
24352433
self._interleaved_err_network_results.append(
24362434
result.relpath
24372435
)
2438-
if result.checkout_error:
2439-
errors.append(result.checkout_error)
2436+
if result.checkout_errors:
2437+
errors.extend(result.checkout_errors)
24402438
self._interleaved_err_checkout = True
24412439
self._interleaved_err_checkout_results.append(
24422440
result.relpath

tests/test_subcmds_sync.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,8 @@ def test_worker_successful_sync(self):
810810
result = result_obj.results[0]
811811
self.assertTrue(result.fetch_success)
812812
self.assertTrue(result.checkout_success)
813-
self.assertIsNone(result.fetch_error)
814-
self.assertIsNone(result.checkout_error)
813+
self.assertEqual(result.fetch_errors, [])
814+
self.assertEqual(result.checkout_errors, [])
815815
project.Sync_NetworkHalf.assert_called_once()
816816
project.Sync_LocalHalf.assert_called_once()
817817

@@ -833,8 +833,8 @@ def test_worker_fetch_fails(self):
833833

834834
self.assertFalse(result.fetch_success)
835835
self.assertFalse(result.checkout_success)
836-
self.assertEqual(result.fetch_error, fetch_error)
837-
self.assertIsNone(result.checkout_error)
836+
self.assertEqual(result.fetch_errors, [fetch_error])
837+
self.assertEqual(result.checkout_errors, [])
838838
project.Sync_NetworkHalf.assert_called_once()
839839
project.Sync_LocalHalf.assert_not_called()
840840

@@ -871,7 +871,7 @@ def test_worker_fetch_fails_exception(self):
871871

872872
self.assertFalse(result.fetch_success)
873873
self.assertFalse(result.checkout_success)
874-
self.assertEqual(result.fetch_error, fetch_error)
874+
self.assertEqual(result.fetch_errors, [fetch_error])
875875
project.Sync_NetworkHalf.assert_called_once()
876876
project.Sync_LocalHalf.assert_not_called()
877877

@@ -893,8 +893,8 @@ def test_worker_checkout_fails(self):
893893

894894
self.assertTrue(result.fetch_success)
895895
self.assertFalse(result.checkout_success)
896-
self.assertIsNone(result.fetch_error)
897-
self.assertEqual(result.checkout_error, checkout_error)
896+
self.assertEqual(result.fetch_errors, [])
897+
self.assertEqual(result.checkout_errors, [checkout_error])
898898
project.Sync_NetworkHalf.assert_called_once()
899899
project.Sync_LocalHalf.assert_called_once()
900900

0 commit comments

Comments
 (0)