googleads / google-ads-python

Google Ads API Client Library for Python
Apache License 2.0
483 stars 474 forks source link

TypeError: exceptions must derive from BaseException #862

Open martinagrzybowska opened 2 months ago

martinagrzybowska commented 2 months ago

Hi, this is a weird bug which happens really often, though I have been unable to find out what type of error from the GRCP causes it, since the exception in this library always overshadows it. I think it might be caused by the library trying to raise something that is not an exception in line self._get_error_from_response(response).

Traceback (most recent call last): File "/app/ads_service/ads_client_handler.py", line 42, in inner return wrapped_function(self) File "/app/ads_service/search/search_service.py", line 15, in post result = self.search_stream( File "/app/ads_service/ads_client_handler.py", line 29, in inner return wrapped_function(*args, **kwargs) File "/app/ads_service/search/search_handler.py", line 22, in search_stream for batch in stream: File "/usr/local/lib/python3.9/site-packages/google/api_core/grpc_helpers.py", line 119, in __next__ return next(self._wrapped) File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/response_wrappers.py", line 108, in __next__ raise e File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/response_wrappers.py", line 105, in __next__ self._failure_handler(self._underlay_call) File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/exception_interceptor.py", line 71, in _handle_grpc_failure raise self._get_error_from_response(response) TypeError: exceptions must derive from BaseException

Expected behavior: The exception_interceptor throws an actual exception and does not result in exception itself while parsing it.

Client library version and API version: Client library version: 24.0.0 Google Ads API version: default to the current GoogleAdsClient from this library

Flask==3.0.0 gunicorn==20.1.0 google-ads==24.0.0 marshmallow==3.18.0 flask_restful==0.3.9 google-auth==2.17.0 google-cloud-logging==3.2.2 google-cloud-secret-manager==2.16.1 python-dotenv==1.0.0 grpcio==1.60.0 pytest==7.4.2

BenRKarl commented 1 month ago

@martinagrzybowska can you share some more details about how you're able to trigger this error?

martinagrzybowska commented 1 month ago

@martinagrzybowska can you share some more details about how you're able to trigger this error?

I wrote, I am unable to recreate that error at will. I suspect it might happen when the Google Ads API suddenly cuts the connection. Here is an example of a whole stack trace, though it is not the same every time.

`Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 793, in urlopen response = self._make_request( File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 537, in _make_request response = conn.getresponse() File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 466, in getresponse httplib_response = super().getresponse() File "/usr/local/lib/python3.9/http/client.py", line 1349, in getresponse response.begin() File "/usr/local/lib/python3.9/http/client.py", line 316, in begin version, status, reason = self._read_status() File "/usr/local/lib/python3.9/http/client.py", line 277, in _read_status line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") File "/usr/local/lib/python3.9/socket.py", line 704, in readinto return self._sock.recv_into(b) File "/usr/local/lib/python3.9/ssl.py", line 1241, in recv_into return self.read(nbytes, buffer) File "/usr/local/lib/python3.9/ssl.py", line 1099, in read return self._sslobj.read(len, buffer) ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 589, in send resp = conn.urlopen( File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 847, in urlopen retries = retries.increment( File "/usr/local/lib/python3.9/site-packages/urllib3/util/retry.py", line 470, in increment raise reraise(type(error), error, _stacktrace) File "/usr/local/lib/python3.9/site-packages/urllib3/util/util.py", line 38, in reraise raise value.with_traceback(tb) File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 793, in urlopen response = self._make_request( File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 537, in _make_request response = conn.getresponse() File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 466, in getresponse httplib_response = super().getresponse() File "/usr/local/lib/python3.9/http/client.py", line 1349, in getresponse response.begin() File "/usr/local/lib/python3.9/http/client.py", line 316, in begin version, status, reason = self._read_status() File "/usr/local/lib/python3.9/http/client.py", line 277, in _read_status line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") File "/usr/local/lib/python3.9/socket.py", line 704, in readinto return self._sock.recv_into(b) File "/usr/local/lib/python3.9/ssl.py", line 1241, in recv_into return self.read(nbytes, buffer) File "/usr/local/lib/python3.9/ssl.py", line 1099, in read return self._sslobj.read(len, buffer) urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/response_wrappers.py", line 88, in next message = next(self._underlay_call) File "/usr/local/lib/python3.9/site-packages/grpc/_channel.py", line 540, in next return self._next() File "/usr/local/lib/python3.9/site-packages/grpc/_channel.py", line 773, in _next return self._next_response() File "/usr/local/lib/python3.9/site-packages/grpc/_channel.py", line 735, in _next_response self._consume_next_event() File "/usr/local/lib/python3.9/site-packages/grpc/_channel.py", line 730, in _consume_next_event callback() File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/logging_interceptor.py", line 362, in on_rpc_complete self.log_request(client_call_details, request, response_future) File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/logging_interceptor.py", line 310, in log_request self.log_successful_request( File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/logging_interceptor.py", line 228, in log_successful_request self.logger.info( File "/usr/local/lib/python3.9/logging/init.py", line 1446, in info self._log(INFO, msg, args, kwargs) File "/usr/local/lib/python3.9/logging/init.py", line 1589, in _log self.handle(record) File "/usr/local/lib/python3.9/logging/init.py", line 1599, in handle self.callHandlers(record) File "/usr/local/lib/python3.9/logging/init.py", line 1661, in callHandlers hdlr.handle(record) File "/usr/local/lib/python3.9/logging/init.py", line 952, in handle self.emit(record) File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/handlers/handlers.py", line 208, in emit self.transport.send( File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/handlers/transports/sync.py", line 56, in send self.logger.log( File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/logger.py", line 255, in log self.log_text(message, client=client, kw) File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/logger.py", line 197, in log_text self._do_log(client, TextEntry, text, kw) File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/logger.py", line 166, in _do_log client.logging_api.write_entries(entries, partial_success=partial_success) File "/usr/local/lib/python3.9/site-packages/google/cloud/logging_v2/_http.py", line 192, in write_entries self.api_request(method="POST", path="/entries:write", data=data) File "/usr/local/lib/python3.9/site-packages/google/cloud/_http/init.py", line 482, in api_request response = self._make_request( File "/usr/local/lib/python3.9/site-packages/google/cloud/_http/init.py", line 341, in _make_request return self._do_request( File "/usr/local/lib/python3.9/site-packages/google/cloud/_http/init.py", line 379, in _do_request return self.http.request( File "/usr/local/lib/python3.9/site-packages/google/auth/transport/requests.py", line 549, in request response = super(AuthorizedSession, self).request( File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 589, in request resp = self.send(prep, send_kwargs) File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 604, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/app/ads_service/ads_client_handler.py", line 44, in inner return wrapped_function(self) File "/app/ads_service/search/search_service.py", line 16, in post result = self.search_stream( File "/app/ads_service/ads_client_handler.py", line 31, in inner return wrapped_function(*args, **kwargs) File "/app/ads_service/search/search_handler.py", line 34, in search_stream for batch in stream: File "/usr/local/lib/python3.9/site-packages/google/api_core/grpc_helpers.py", line 116, in next return next(self._wrapped) File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/response_wrappers.py", line 108, in next raise e File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/response_wrappers.py", line 105, in next self._failure_handler(self._underlay_call) File "/usr/local/lib/python3.9/site-packages/google/ads/googleads/interceptors/exception_interceptor.py", line 71, in _handle_grpc_failure raise self._get_error_from_response(response) TypeError: exceptions must derive from BaseException `