3030from google .cloud .bigtable .data .exceptions import MutationsExceptionGroup
3131from google .cloud .bigtable .data .exceptions import ShardedReadRowsExceptionGroup
3232from google .cloud .bigtable .data .exceptions import RetryExceptionGroup
33+ from google .cloud .bigtable .data ._helpers import _retry_exception_factory
3334from google .cloud .bigtable_v2 .types .response_params import ResponseParams
3435from google .protobuf .message import DecodeError
36+ from google .api_core .retry import RetryFailureReason
3537
3638if TYPE_CHECKING :
3739 from google .cloud .bigtable .data ._metrics .handlers ._base import MetricsHandler
@@ -377,13 +379,17 @@ def end_with_success(self):
377379 """
378380 return self .end_with_status (StatusCode .OK )
379381
380- def build_wrapped_predicate (
381- self , inner_predicate : Callable [[Exception ], bool ]
382+ def build_wrapped_fn_handlers (
383+ self ,
384+ inner_predicate : Callable [[Exception ], bool ],
382385 ) -> Callable [[Exception ], bool ]:
383386 """
384- Wrapps a predicate to include metrics tracking. Any call to the resulting predicate
385- is assumed to be an rpc failure, and will either mark the end of the active attempt
386- or the end of the operation.
387+ One way to track metrics is by wrapping the `predicate` and `exception_factory`
388+ arguments of `api_core.Retry`. This will notify us when an exception occurs so
389+ we can track it.
390+
391+ This function retruns wrapped versions of the `predicate` and `exception_factory`
392+ to be passed down when building the `Retry` object.
387393
388394 Args:
389395 - predicate: The predicate to wrap.
@@ -397,7 +403,17 @@ def wrapped_predicate(exc: Exception) -> bool:
397403 self .end_with_status (exc )
398404 return inner_result
399405
400- return wrapped_predicate
406+ def wrapped_exception_factory (
407+ exc_list : list [Exception ],
408+ reason : RetryFailureReason ,
409+ timeout_val : float | None ,
410+ ) -> tuple [Exception , Exception | None ]:
411+ exc , source = _retry_exception_factory (exc_list , reason , timeout_val )
412+ if reason != RetryFailureReason .NON_RETRYABLE_ERROR :
413+ self ._operation_metrics .end_with_status (exc )
414+ return exc , source
415+
416+ return wrapped_predicate , wrapped_exception_factory
401417
402418 @staticmethod
403419 def _exc_to_status (exc : Exception ) -> StatusCode :
0 commit comments