1515
1616import time
1717from functools import wraps
18- from grpc import RpcError
1918from google .cloud .bigtable .data ._metrics .data_model import (
2019 OPERATION_INTERCEPTOR_METADATA_KEY ,
2120)
@@ -66,6 +65,26 @@ def wrapper(self, continuation, client_call_details, request):
6665 return wrapper
6766
6867
68+ def _end_attempt (operation , exc , metadata ):
69+ """Helper to add metadata and exception to an operation"""
70+ if metadata is not None :
71+ operation .add_response_metadata (metadata )
72+ if exc is not None :
73+ # end attempt. If it succeeded, let higher levels decide when to end operation
74+ operation .end_attempt_with_status (exc )
75+
76+
77+ @CrossSync .convert
78+ async def _get_metadata (source ):
79+ """Helper to extract metadata from a call or RpcError"""
80+ try :
81+ return (await source .trailing_metadata () or []) + (
82+ await source .initial_metadata () or []
83+ )
84+ except Exception :
85+ # ignore errors while fetching metadata
86+ return None
87+
6988@CrossSync .convert_class (sync_name = "BigtableMetricsInterceptor" )
7089class AsyncBigtableMetricsInterceptor (
7190 UnaryUnaryClientInterceptor , UnaryStreamClientInterceptor , MetricsHandler
@@ -109,25 +128,14 @@ async def intercept_unary_unary(
109128 metadata = None
110129 try :
111130 call = await continuation (client_call_details , request )
112- metadata = ( await call . trailing_metadata () or []) + ( await call . initial_metadata () or [] )
131+ metadata = await _get_metadata ( call )
113132 return call
114- except RpcError as rpc_error :
115- # attempt extracting metadata from error
116- try :
117- metadata = (await rpc_error .trailing_metadata () or []) + (await rpc_error .initial_metadata () or [])
118- except Exception :
119- pass
133+ except Exception as rpc_error :
134+ metadata = await _get_metadata (rpc_error )
120135 encountered_exc = rpc_error
121136 raise rpc_error
122- except Exception as e :
123- encountered_exc = e
124- raise
125137 finally :
126- if metadata is not None :
127- operation .add_response_metadata (metadata )
128- if encountered_exc is not None :
129- # end attempt. If it succeeded, let higher levels decide when to end operation
130- operation .end_attempt_with_status (encountered_exc )
138+ _end_attempt (operation , encountered_exc , metadata )
131139
132140 @CrossSync .convert
133141 @_with_operation_from_metadata
@@ -146,30 +154,17 @@ async def response_wrapper(call):
146154 )
147155 has_first_response = True
148156 yield response
149-
150-
151157 except Exception as e :
158+ # handle errors while processing stream
152159 encountered_exc = e
153160 raise
154161 finally :
155162 if call is not None :
156- metadata = (await call .trailing_metadata () or []) + (await call .initial_metadata () or [])
157- operation .add_response_metadata (metadata )
158- if encountered_exc is not None :
159- # end attempt. If it succeeded, let higher levels decide when to end operation
160- operation .end_attempt_with_status (encountered_exc )
163+ _end_attempt (operation , encountered_exc , await _get_metadata (call ))
161164
162165 try :
163166 return response_wrapper (await continuation (client_call_details , request ))
164- except RpcError as rpc_error :
165- # attempt extracting metadata from error
166- try :
167- metadata = (await rpc_error .trailing_metadata () or []) + (await rpc_error .initial_metadata () or [])
168- operation .add_response_metadata (metadata )
169- except Exception :
170- pass
171- operation .end_attempt_with_status (rpc_error )
172- raise rpc_error
173- except Exception as e :
174- operation .end_attempt_with_status (e )
175- raise
167+ except Exception as rpc_error :
168+ # handle errors while intializing stream
169+ _end_attempt (operation , rpc_error , await _get_metadata (rpc_error ))
170+ raise rpc_error
0 commit comments