19
19
so it translates the error to a GoogleAdsFailure instance and raises it.
20
20
"""
21
21
22
- import grpc
23
-
24
- from grpc import UnaryUnaryClientInterceptor , UnaryStreamClientInterceptor
22
+ from typing import Any , Callable , TypeVar , Union , NoReturn
25
23
24
+ import grpc
25
+ from grpc import (
26
+ UnaryUnaryClientInterceptor ,
27
+ UnaryStreamClientInterceptor ,
28
+ ClientCallDetails ,
29
+ Call ,
30
+ )
31
+
32
+ from google .ads .googleads .errors import GoogleAdsException
26
33
from .interceptor import Interceptor
27
34
from .response_wrappers import _UnaryStreamWrapper , _UnaryUnaryWrapper
28
35
36
+ # Define generic types for request and response messages.
37
+ # These are typically protobuf message instances.
38
+ RequestType = TypeVar ("RequestType" )
39
+ ResponseType = TypeVar ("ResponseType" )
40
+ # Type for the continuation callable in intercept_unary_unary
41
+ UnaryUnaryContinuation = Callable [
42
+ [ClientCallDetails , RequestType ], Union [Call , Any ]
43
+ ]
44
+ # Type for the continuation callable in intercept_unary_stream
45
+ UnaryStreamContinuation = Callable [
46
+ [ClientCallDetails , RequestType ], Union [grpc .Call , Any ]
47
+ ]
48
+
29
49
30
50
class ExceptionInterceptor (
31
51
Interceptor , UnaryUnaryClientInterceptor , UnaryStreamClientInterceptor
32
52
):
33
53
"""An interceptor that wraps rpc exceptions."""
34
54
35
- def __init__ (self , api_version , use_proto_plus = False ):
55
+ _api_version : str
56
+ _use_proto_plus : bool
57
+
58
+ def __init__ (self , api_version : str , use_proto_plus : bool = False ):
36
59
"""Initializes the ExceptionInterceptor.
37
60
38
61
Args:
39
- api_version: a str of the API version of the request.
40
- use_proto_plus: a boolean of whether returned messages should be
62
+ api_version: A str of the API version of the request.
63
+ use_proto_plus: A boolean of whether returned messages should be
41
64
proto_plus or protobuf.
42
65
"""
43
66
super ().__init__ (api_version )
44
67
self ._api_version = api_version
45
68
self ._use_proto_plus = use_proto_plus
46
69
47
- def _handle_grpc_failure (self , response ) :
70
+ def _handle_grpc_failure (self , response : grpc . Call ) -> NoReturn :
48
71
"""Attempts to convert failed responses to a GoogleAdsException object.
49
72
50
73
Handles failed gRPC responses of by attempting to convert them
@@ -61,16 +84,23 @@ def _handle_grpc_failure(self, response):
61
84
Raises:
62
85
GoogleAdsException: If the exception's trailing metadata
63
86
indicates that it is a GoogleAdsException.
64
- RpcError: If the exception's is a gRPC exception but the trailing
87
+ grpc. RpcError: If the exception's is a gRPC exception but the trailing
65
88
metadata is empty or is not indicative of a GoogleAdsException,
66
89
or if the exception has a status code of INTERNAL or
67
90
RESOURCE_EXHAUSTED.
68
91
Exception: If not a GoogleAdsException or RpcException the error
69
92
will be raised as-is.
70
93
"""
71
- raise self ._get_error_from_response (response )
72
-
73
- def intercept_unary_unary (self , continuation , client_call_details , request ):
94
+ # Assuming _get_error_from_response is defined in the parent Interceptor
95
+ # and raises an exception, so this method effectively has -> NoReturn
96
+ raise self ._get_error_from_response (response ) # type: ignore
97
+
98
+ def intercept_unary_unary (
99
+ self ,
100
+ continuation : UnaryUnaryContinuation [RequestType , ResponseType ],
101
+ client_call_details : ClientCallDetails ,
102
+ request : RequestType ,
103
+ ) -> Union [_UnaryUnaryWrapper , ResponseType , Call ]:
74
104
"""Intercepts and wraps exceptions in the rpc response.
75
105
76
106
Overrides abstract method defined in grpc.UnaryUnaryClientInterceptor.
@@ -79,32 +109,41 @@ def intercept_unary_unary(self, continuation, client_call_details, request):
79
109
continuation: a function to continue the request process.
80
110
client_call_details: a grpc._interceptor._ClientCallDetails
81
111
instance containing request metadata.
82
- request: a SearchGoogleAdsRequest or SearchGoogleAdsStreamRequest
83
- message class instance.
112
+ request: A protobuf message class instance for the request.
84
113
85
114
Returns:
86
- A grpc.Call instance representing a service response.
115
+ A _UnaryUnaryWrapper instance if successful, otherwise this method
116
+ will raise an exception via _handle_grpc_failure. The actual
117
+ return type from continuation can be grpc.Call or a future-like
118
+ object that has an `exception()` method.
87
119
88
120
Raises:
89
121
GoogleAdsException: If the exception's trailing metadata
90
122
indicates that it is a GoogleAdsException.
91
- RpcError: If the exception's trailing metadata is empty or is not
123
+ grpc. RpcError: If the exception's trailing metadata is empty or is not
92
124
indicative of a GoogleAdsException, or if the exception has a
93
125
status code of INTERNAL or RESOURCE_EXHAUSTED.
94
126
"""
95
- response = continuation (client_call_details , request )
96
- exception = response .exception ()
127
+ response_call = continuation (client_call_details , request )
128
+ # response_call is often a grpc.Call / grpc.Future in unary-unary.
129
+ # It has an exception() method to check for errors.
130
+ exception = response_call .exception ()
97
131
98
132
if exception :
99
- self ._handle_grpc_failure (response )
133
+ # _handle_grpc_failure is guaranteed to raise, so the execution stops here.
134
+ self ._handle_grpc_failure (response_call )
100
135
else :
136
+ # If there's no exception, wrap the successful response.
101
137
return _UnaryUnaryWrapper (
102
- response , use_proto_plus = self ._use_proto_plus
138
+ response_call , use_proto_plus = self ._use_proto_plus
103
139
)
104
140
105
141
def intercept_unary_stream (
106
- self , continuation , client_call_details , request
107
- ):
142
+ self ,
143
+ continuation : UnaryStreamContinuation [RequestType , ResponseType ],
144
+ client_call_details : ClientCallDetails ,
145
+ request : RequestType ,
146
+ ) -> _UnaryStreamWrapper :
108
147
"""Intercepts and wraps exceptions in the rpc response.
109
148
110
149
Overrides abstract method defined in grpc.UnaryStreamClientInterceptor.
@@ -113,22 +152,21 @@ def intercept_unary_stream(
113
152
continuation: a function to continue the request process.
114
153
client_call_details: a grpc._interceptor._ClientCallDetails
115
154
instance containing request metadata.
116
- request: a SearchGoogleAdsRequest or SearchGoogleAdsStreamRequest
117
- message class instance.
155
+ request: A protobuf message class instance for the request.
118
156
119
157
Returns:
120
- A grpc.Call instance representing a service response.
158
+ A _UnaryStreamWrapper instance that wraps the stream response.
121
159
122
160
Raises:
123
- GoogleAdsException: If the exception's trailing metadata
124
- indicates that it is a GoogleAdsException.
125
- RpcError: If the exception's trailing metadata is empty or is not
126
- indicative of a GoogleAdsException, or if the exception has a
127
- status code of INTERNAL or RESOURCE_EXHAUSTED.
161
+ This method itself doesn't raise directly but passes
162
+ _handle_grpc_failure to _UnaryStreamWrapper, which may raise if
163
+ errors occur during streaming or if the initial call fails.
128
164
"""
129
- response = continuation (client_call_details , request )
165
+ # In unary-stream, continuation returns an object that is an iterator
166
+ # of responses, often a grpc.Call.
167
+ response_stream_call = continuation (client_call_details , request )
130
168
return _UnaryStreamWrapper (
131
- response ,
169
+ response_stream_call , # type: ignore
132
170
self ._handle_grpc_failure ,
133
171
use_proto_plus = self ._use_proto_plus ,
134
172
)
0 commit comments