Skip to content

Commit

Permalink
Fix for summary param error - Added retry logic (#239)
Browse files Browse the repository at this point in the history
* upgrade the facebook sdk version

* place the facebook_business sdk locally and add retry for the summary param error

* Monkey patch the original function(call) of facebook business sdk

* update logger statement
  • Loading branch information
sgandhi1311 authored Apr 15, 2024
1 parent 6aeb27e commit 534bded
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 1.20.2
* Bump facebook_business SDK to v19.0.2 [#238](https://github.com/singer-io/tap-facebook/pull/239)

## 1.20.1
* Bump facebook_business SDK to v19.0.0 [#238](https://github.com/singer-io/tap-facebook/pull/238)

Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from setuptools import setup

setup(name='tap-facebook',
version='1.20.1',
version='1.20.2',
description='Singer.io tap for extracting data from the Facebook Ads API',
author='Stitch',
url='https://singer.io',
Expand All @@ -12,8 +12,8 @@
install_requires=[
'attrs==17.3.0',
'backoff==2.2.1',
'facebook_business==19.0.2',
'pendulum==1.2.0',
'facebook_business==19.0.0',
'requests==2.20.0',
'singer-python==6.0.0',
],
Expand Down
52 changes: 52 additions & 0 deletions tap_facebook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import requests
import backoff

import sys

import re
import singer
import singer.metrics as metrics
from singer import utils, metadata
Expand Down Expand Up @@ -87,6 +90,55 @@

CONFIG = {}

def retry_on_summary_param_error(backoff_type, exception, **wait_gen_kwargs):
"""
At times, the Facebook Graph API exhibits erratic behavior,
triggering errors related to the Summary parameter with a status code of 400.
However, upon retrying, the API functions as expected.
"""
def log_retry_attempt(details):
_, exception, _ = sys.exc_info()
LOGGER.info('Caught Summary param error after %s tries. Waiting %s more seconds then retrying...',
details["tries"],
details["wait"])

def should_retry_api_error(exception):

# Define the regular expression pattern
pattern = r'\(#100\) Cannot include [\w, ]+ in summary param because they weren\'t there while creating the report run(?:\. All available values are: )?'
if isinstance(exception, FacebookRequestError):
return (exception.http_status()==400 and re.match(pattern, exception._error['message']))
return False

return backoff.on_exception(
backoff_type,
exception,
jitter=None,
on_backoff=log_retry_attempt,
giveup=lambda exc: not should_retry_api_error(exc),
**wait_gen_kwargs
)

original_call = FacebookAdsApi.call

@retry_on_summary_param_error(backoff.expo, (FacebookRequestError), max_tries=5, factor=5)
def call_with_retry(self, method, path, params=None, headers=None, files=None, url_override=None, api_version=None,):
"""
Adding the retry decorator on the original function call
"""
return original_call(
self,
method,
path,
params,
headers,
files,
url_override,
api_version,)

FacebookAdsApi.call = call_with_retry


class TapFacebookException(Exception):
pass

Expand Down

0 comments on commit 534bded

Please sign in to comment.