Skip to content

Commit 8789eac

Browse files
authored
Source Facebook Marketing: add retry for transient error (#37320)
Signed-off-by: Artem Inzhyyants <[email protected]>
1 parent df2bb71 commit 8789eac

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ data:
1010
connectorSubtype: api
1111
connectorType: source
1212
definitionId: e7778cfc-e97c-4458-9ecb-b4f2bba8946c
13-
dockerImageTag: 2.1.2
13+
dockerImageTag: 2.1.3
1414
dockerRepository: airbyte/source-facebook-marketing
1515
documentationUrl: https://docs.airbyte.com/integrations/sources/facebook-marketing
1616
githubIssueLabel: source-facebook-marketing

airbyte-integrations/connectors/source-facebook-marketing/pyproject.toml

+1-1
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 = "2.1.2"
6+
version = "2.1.3"
77
name = "source-facebook-marketing"
88
description = "Source implementation for Facebook Marketing."
99
authors = [ "Airbyte <[email protected]>",]

airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/common.py

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import http.client
66
import logging
7+
import re
78
import sys
89
from typing import Any
910

@@ -84,6 +85,12 @@ def revert_request_record_limit(details):
8485
# set the flag to the api class that the `limit` param is restored
8586
details.get("args")[0].request_record_limit_is_reduced = False
8687

88+
def is_transient_cannot_include_error(exc: FacebookRequestError) -> bool:
89+
"""After migration to API v19.0, some customers randomly face a BAD_REQUEST error (OAuthException) with the pattern:"Cannot include ..."
90+
According to the last comment in https://developers.facebook.com/community/threads/286697364476462/, this might be a transient issue that can be solved with a retry."""
91+
pattern = r"Cannot include .* in summary param because they weren't there while creating the report run."
92+
return bool(exc.http_status() == http.client.BAD_REQUEST and re.search(pattern, exc.api_error_message()))
93+
8794
def should_retry_api_error(exc):
8895
if isinstance(exc, FacebookRequestError):
8996
call_rate_limit_error = exc.api_error_code() in FACEBOOK_RATE_LIMIT_ERROR_CODES
@@ -98,6 +105,7 @@ def should_retry_api_error(exc):
98105
unknown_error,
99106
call_rate_limit_error,
100107
batch_timeout_error,
108+
is_transient_cannot_include_error(exc),
101109
connection_reset_error,
102110
temporary_oauth_error,
103111
server_error,

airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_errors.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,6 @@ def test_config_error_during_account_info_read(self, requests_mock, name, friend
346346
assert error.failure_type == FailureType.config_error
347347
assert friendly_msg in error.message
348348

349-
# @pytest.mark.parametrize("name, friendly_msg, config_error_response", [CONFIG_ERRORS[-1]])
350349
@pytest.mark.parametrize("name, friendly_msg, config_error_response", CONFIG_ERRORS)
351350
def test_config_error_during_actual_nodes_read(self, requests_mock, name, friendly_msg, config_error_response):
352351
"""Error raised during actual nodes read"""
@@ -422,6 +421,37 @@ def test_config_error_insights_during_actual_nodes_read(self, requests_mock, nam
422421
assert error.failure_type == FailureType.config_error
423422
assert friendly_msg in error.message
424423

424+
def test_retry_for_cannot_include_error(self, requests_mock):
425+
"""Error raised randomly for insights stream. Oncall: https://github.com/airbytehq/oncall/issues/4868 """
426+
427+
api = API(access_token=some_config["access_token"], page_size=100)
428+
stream = AdsInsights(
429+
api=api,
430+
account_ids=some_config["account_ids"],
431+
start_date=datetime(2010, 1, 1),
432+
end_date=datetime(2011, 1, 1),
433+
fields=["account_id", "account_currency"],
434+
insights_lookback_window=28,
435+
)
436+
requests_mock.register_uri("GET", f"{act_url}", [ad_account_response])
437+
response = {
438+
"status_code": 400,
439+
"json": {
440+
"error": {
441+
"message": "(#100) Cannot include video_avg_time_watched_actions, video_continuous_2_sec_watched_actions in summary param because they weren't there while creating the report run.",
442+
"type": "OAuthException",
443+
"code": 100
444+
}
445+
},
446+
}
447+
call_insights = requests_mock.register_uri("GET", f"{act_url}insights", [response])
448+
449+
try:
450+
slice = list(stream.stream_slices(sync_mode=SyncMode.full_refresh, stream_state={}))[0]
451+
list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice, stream_state={}))
452+
except Exception:
453+
assert call_insights.call_count == 5
454+
425455
@pytest.mark.parametrize(
426456
"failure_response",
427457
(

docs/integrations/sources/facebook-marketing.md

+1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ The Facebook Marketing connector uses the `lookback_window` parameter to repeate
200200

201201
| Version | Date | Pull Request | Subject |
202202
|:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
203+
| 2.1.3 | 2024-04-16 | [37320](https://github.com/airbytehq/airbyte/pull/37320) | Add retry for transient error |
203204
| 2.1.2 | 2024-03-29 | [36689](https://github.com/airbytehq/airbyte/pull/36689) | Fix key error `account_id` for custom reports. |
204205
| 2.1.1 | 2024-03-18 | [36025](https://github.com/airbytehq/airbyte/pull/36025) | Fix start_date selection behaviour |
205206
| 2.1.0 | 2024-03-12 | [35978](https://github.com/airbytehq/airbyte/pull/35978) | Upgrade CDK to start emitting record counts with state and full refresh state |

0 commit comments

Comments
 (0)