Skip to content

Commit 1233f2e

Browse files
author
Baz
authored
🎉 Source Google Ads: Add Unrecognized Field description while check_connection (#36208)
1 parent 916347f commit 1233f2e

File tree

10 files changed

+125
-94
lines changed

10 files changed

+125
-94
lines changed

‎airbyte-integrations/connectors/source-google-ads/metadata.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ data:
1111
connectorSubtype: api
1212
connectorType: source
1313
definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50
14-
dockerImageTag: 3.3.6
14+
dockerImageTag: 3.3.7
1515
dockerRepository: airbyte/source-google-ads
1616
documentationUrl: https://docs.airbyte.com/integrations/sources/google-ads
1717
githubIssueLabel: source-google-ads

‎airbyte-integrations/connectors/source-google-ads/poetry.lock

Lines changed: 81 additions & 80 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎airbyte-integrations/connectors/source-google-ads/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
33
build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
6-
version = "3.3.6"
6+
version = "3.3.7"
77
name = "source-google-ads"
88
description = "Source implementation for Google Ads."
99
authors = [ "Airbyte <[email protected]>",]

‎airbyte-integrations/connectors/source-google-ads/source_google_ads/config_migrations.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#
44

55

6-
import logging
76
from typing import Any, List, Mapping
87

98
from airbyte_cdk.config_observation import create_connector_config_control_message
@@ -15,8 +14,6 @@
1514

1615
from .utils import GAQL
1716

18-
logger = logging.getLogger("airbyte_logger")
19-
2017
FULL_REFRESH_CUSTOM_TABLE = [
2118
"asset",
2219
"asset_group_listing_group_filter",

‎airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#
44

55

6-
import logging
76
from enum import Enum
87
from typing import Any, Iterable, Iterator, List, Mapping, MutableMapping
98

@@ -16,8 +15,9 @@
1615
from google.auth import exceptions
1716
from proto.marshal.collections import Repeated, RepeatedComposite
1817

18+
from .utils import logger
19+
1920
API_VERSION = "v15"
20-
logger = logging.getLogger("airbyte")
2121

2222

2323
class GoogleAds:
@@ -74,7 +74,12 @@ def get_accessible_accounts(self):
7474
),
7575
max_tries=5,
7676
)
77-
def send_request(self, query: str, customer_id: str, login_customer_id: str = "default") -> Iterator[SearchGoogleAdsResponse]:
77+
def send_request(
78+
self,
79+
query: str,
80+
customer_id: str,
81+
login_customer_id: str = "default",
82+
) -> Iterator[SearchGoogleAdsResponse]:
7883
client = self.get_client(login_customer_id)
7984
search_request = client.get_type("SearchGoogleAdsRequest")
8085
search_request.query = query

‎airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@
4545
UserInterest,
4646
UserLocationView,
4747
)
48-
from .utils import GAQL
49-
50-
logger = logging.getLogger("airbyte")
48+
from .utils import GAQL, logger, traced_exception
5149

5250

5351
class SourceGoogleAds(AbstractSource):
@@ -191,6 +189,7 @@ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) ->
191189
# Check custom query request validity by sending metric request with non-existent time window
192190
for customer in customers:
193191
for query in config.get("custom_queries_array", []):
192+
table_name = query["table_name"]
194193
query = query["query"]
195194
if customer.is_manager_account and self.is_metrics_in_custom_query(query):
196195
logger.warning(
@@ -205,7 +204,14 @@ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) ->
205204
query = IncrementalCustomQuery.insert_segments_date_expr(query, "1980-01-01", "1980-01-01")
206205

207206
query = query.set_limit(1)
208-
response = google_api.send_request(str(query), customer_id=customer.id, login_customer_id=customer.login_customer_id)
207+
try:
208+
response = google_api.send_request(
209+
str(query),
210+
customer_id=customer.id,
211+
login_customer_id=customer.login_customer_id,
212+
)
213+
except Exception as exc:
214+
traced_exception(exc, customer.id, False, table_name)
209215
# iterate over the response otherwise exceptions will not be raised!
210216
for _ in response:
211217
pass

‎airbyte-integrations/connectors/source-google-ads/source_google_ads/utils.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44

55
import functools
6+
import logging
67
import queue
78
import re
89
import threading
@@ -17,10 +18,12 @@
1718
from google.ads.googleads.errors import GoogleAdsException
1819
from google.ads.googleads.v15.errors.types.authentication_error import AuthenticationErrorEnum
1920
from google.ads.googleads.v15.errors.types.authorization_error import AuthorizationErrorEnum
21+
from google.ads.googleads.v15.errors.types.query_error import QueryErrorEnum
2022
from google.ads.googleads.v15.errors.types.quota_error import QuotaErrorEnum
2123
from google.ads.googleads.v15.errors.types.request_error import RequestErrorEnum
2224
from google.api_core.exceptions import Unauthenticated
23-
from source_google_ads.google_ads import logger
25+
26+
logger = logging.getLogger("airbyte")
2427

2528

2629
def get_resource_name(stream_name: str) -> str:
@@ -54,7 +57,12 @@ def is_error_type(error_value, target_enum_value):
5457
return int(error_value) == int(target_enum_value)
5558

5659

57-
def traced_exception(ga_exception: Union[GoogleAdsException, Unauthenticated], customer_id: str, catch_disabled_customer_error: bool):
60+
def traced_exception(
61+
ga_exception: Union[GoogleAdsException, Unauthenticated],
62+
customer_id: str,
63+
catch_disabled_customer_error: bool,
64+
query_name: Optional[str] = None,
65+
) -> None:
5866
"""Add user-friendly message for GoogleAdsException"""
5967
messages = []
6068
raise_exception = AirbyteTracedException
@@ -100,6 +108,13 @@ def traced_exception(ga_exception: Union[GoogleAdsException, Unauthenticated], c
100108
"https://support.google.com/google-ads/answer/2375392."
101109
)
102110

111+
elif is_error_type(query_error, QueryErrorEnum.QueryError.UNRECOGNIZED_FIELD):
112+
message = (
113+
f"The Custom Query: `{query_name}` has {error.message.lower()} Please make sure the field exists or name entered is valid."
114+
)
115+
# additionally log the error for visability during `check_connection` in UI.
116+
logger.error(message)
117+
103118
elif query_error:
104119
message = f"Incorrect custom query. {error.message}"
105120

‎airbyte-integrations/connectors/source-google-ads/unit_tests/common.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ def __init__(self, name):
9292
"failure_msg": "Error in query: unexpected end of query.",
9393
"error_type": "queryError",
9494
},
95+
"UNRECOGNIZED_FIELD": {
96+
"failure_code": QueryErrorEnum.QueryError.UNRECOGNIZED_FIELD,
97+
"failure_msg": "unrecognized field in the query.",
98+
"error_type": "queryError",
99+
},
95100
"RESOURCE_EXHAUSTED": {"failure_code": QuotaErrorEnum.QuotaError.RESOURCE_EXHAUSTED, "failure_msg": "msg4", "error_type": "quotaError"},
96101
"UNEXPECTED_ERROR": {
97102
"failure_code": AuthorizationErrorEnum.AuthorizationError.UNKNOWN,

‎airbyte-integrations/connectors/source-google-ads/unit_tests/test_errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def mock_get_customers(mocker):
3535
"Failed to access the customer '123'. Ensure the customer is linked to your manager account or check your permissions to access this customer account.",
3636
),
3737
(["QUERY_ERROR"], "Incorrect custom query. Error in query: unexpected end of query."),
38+
(["UNRECOGNIZED_FIELD"], "The Custom Query: `None` has unrecognized field in the query. Please make sure the field exists or name entered is valid."),
3839
(
3940
["RESOURCE_EXHAUSTED"],
4041
(

‎docs/integrations/sources/google-ads.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ Due to a limitation in the Google Ads API which does not allow getting performan
280280

281281
| Version | Date | Pull Request | Subject |
282282
|:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------|
283+
| `3.3.7` | 2024-03-15 | [36208](https://github.com/airbytehq/airbyte/pull/36208) | Added error message when there is the `unrecognized field` inside of the `custom query` |
283284
| `3.3.6` | 2024-03-01 | [35664](https://github.com/airbytehq/airbyte/pull/35664) | Fix error for new customers for incremental events streams |
284285
| `3.3.5` | 2024-02-28 | [35709](https://github.com/airbytehq/airbyte/pull/35709) | Handle 2-Step Verification exception as config error |
285286
| `3.3.4` | 2024-02-21 | [35493](https://github.com/airbytehq/airbyte/pull/35493) | Rolling back the patch 3.3.3 made for `user_interest` steam |

0 commit comments

Comments
 (0)