@@ -272,10 +272,11 @@ def __init__(
272272 self ._exceptions_since_last_raise : int = 0
273273 # keep track of the first and last _exception_list_limit exceptions
274274 self ._exception_list_limit : int = 10
275- self ._oldest_exceptions : list [Exception ] = []
276- self ._newest_exceptions : deque [Exception ] = deque (
275+ self ._oldest_exceptions : list [FailedMutationEntryError ] = []
276+ self ._newest_exceptions : deque [FailedMutationEntryError ] = deque (
277277 maxlen = self ._exception_list_limit
278278 )
279+ # only used by the shim right now.
279280 self ._user_batch_completed_callback : Optional [
280281 Callable [[list [status_pb2 .Status ]], None ]
281282 ] = None
@@ -363,13 +364,17 @@ async def _flush_internal(self, new_entries: list[RowMutationEntry]):
363364 """
364365 # flush new entries
365366 in_process_requests : list [CrossSync .Future [list [FailedMutationEntryError ]]] = []
367+ in_process_batches : list [list [RowMutationEntry ]] = []
366368 async for batch in self ._flow_control .add_to_flow (new_entries ):
367369 batch_task = CrossSync .create_task (
368370 self ._execute_mutate_rows , batch , sync_executor = self ._sync_rpc_executor
369371 )
370372 in_process_requests .append (batch_task )
373+ in_process_batches .append (batch )
371374 # wait for all inflight requests to complete
372- found_exceptions = await self ._wait_for_batch_results (* in_process_requests )
375+ found_exceptions = await self ._wait_for_batch_results (
376+ in_process_requests , in_process_batches
377+ )
373378 # update exception data to reflect any new errors
374379 self ._entries_processed_since_last_raise += len (new_entries )
375380 self ._add_exceptions (found_exceptions )
@@ -419,7 +424,7 @@ async def _execute_mutate_rows(
419424 self ._user_batch_completed_callback (statuses )
420425 return []
421426
422- def _add_exceptions (self , excs : list [Exception ]):
427+ def _add_exceptions (self , excs : list [FailedMutationEntryError ]):
423428 """
424429 Add new list of exceptions to internal store. To avoid unbounded memory,
425430 the batcher will store the first and last _exception_list_limit exceptions,
@@ -519,26 +524,27 @@ def _on_exit(self):
519524 @staticmethod
520525 @CrossSync .convert
521526 async def _wait_for_batch_results (
522- * tasks : CrossSync .Future [list [FailedMutationEntryError ]]
523- | CrossSync .Future [None ],
524- ) -> list [Exception ]:
527+ tasks : Sequence [
528+ CrossSync .Future [list [FailedMutationEntryError ]] | CrossSync .Future [None ]
529+ ],
530+ batches : Sequence [list [RowMutationEntry ]],
531+ ) -> list [FailedMutationEntryError ]:
525532 """
526533 Takes in a list of futures representing _execute_mutate_rows tasks,
527534 waits for them to complete, and returns a list of errors encountered.
528535
529536 Args:
530537 *tasks: futures representing _execute_mutate_rows or _flush_internal tasks
531538 Returns:
532- list[Exception]:
533- list of Exceptions encountered by any of the tasks. Errors are expected
534- to be FailedMutationEntryError, representing a failed mutation operation.
535- If a task fails with a different exception, it will be included in the
536- output list. Successful tasks will not be represented in the output list.
539+ list[FailedMutationEntryError]:
540+ list of FailedMutationEntryError encountered by any of the tasks,
541+ representing a failed mutation operation.
542+ Successful tasks will not be represented in the output list.
537543 """
538544 if not tasks :
539545 return []
540- exceptions : list [Exception ] = []
541- for task in tasks :
546+ exceptions : list [FailedMutationEntryError ] = []
547+ for task , batch in list ( zip ( tasks , batches )) :
542548 if CrossSync .is_async :
543549 # futures don't need to be awaited in sync mode
544550 await task
@@ -550,6 +556,16 @@ async def _wait_for_batch_results(
550556 # strip index information
551557 exc .index = None
552558 exceptions .extend (exc_list )
553- except Exception as e :
559+ except FailedMutationEntryError as e :
554560 exceptions .append (e )
561+ except Exception as e :
562+ exceptions .extend (
563+ [
564+ FailedMutationEntryError (
565+ failed_idx = None , failed_mutation_entry = entry , cause = e
566+ )
567+ for entry in batch
568+ ]
569+ )
570+
555571 return exceptions
0 commit comments