Skip to content

Commit 044d449

Browse files
authored
Merge pull request #8 from Netuitive/fix/issue-7
Handle 403 and other HTTP errors better
2 parents 7892c8b + c118a1c commit 044d449

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

netuitive/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def __init__(self, url='https://api.app.netuitive.com/ingest',
4646
self.element_dict = {}
4747
self.disabled = False
4848
self.kill_codes = [410, 418]
49+
self.post_error_count = 0
50+
self.max_post_errors = 10
4951

5052
def post(self, element):
5153
"""
@@ -88,6 +90,8 @@ def post(self, element):
8890

8991
resp.close()
9092

93+
self.post_error_count = 0
94+
9195
return(True)
9296

9397
else:
@@ -112,11 +116,19 @@ def post(self, element):
112116
logging.exception('Posting has been disabled.'
113117
'See previous errors for details.')
114118
else:
119+
self.post_error_count += 1
120+
if self.post_error_count > self.max_post_errors:
121+
element.clear_samples()
122+
115123
logging.exception(
116124
'error posting payload to api ingest endpoint (%s): %s',
117125
self.dataurl, e)
118126

119127
except Exception as e:
128+
self.post_error_count += 1
129+
if self.post_error_count > self.max_post_errors:
130+
element.clear_samples() # pragma: no cover
131+
120132
logging.exception(
121133
'error posting payload to api ingest endpoint (%s): %s',
122134
self.dataurl, e)

tests/test_netuitive_client.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,37 @@ def test_failure_general_http(self, mock_logging, mock_post):
126126
self.assertEqual(mock_logging.exception.call_args_list[0][0][
127127
0], 'error posting payload to api ingest endpoint (%s): %s')
128128

129+
@mock.patch('netuitive.client.urllib2.urlopen')
130+
@mock.patch('netuitive.client.logging')
131+
def test_repeat_failure_general_http(self, mock_logging, mock_post):
132+
133+
a = netuitive.Client(api_key='apikey')
134+
135+
e = netuitive.Element()
136+
137+
e.add_sample(
138+
'nonsparseDataStrategy', 1434110794, 1, 'COUNTER', host='hostname')
139+
140+
errs = [403, 429, 503, 404, 503, 204, 307, 302, 405, 413]
141+
142+
for i in range(a.max_post_errors):
143+
mock_post.return_value = MockResponse(code=errs[i])
144+
mock_post.side_effect = urllib2.HTTPError(
145+
a.url, errs[i], '', {}, None)
146+
147+
resp = a.post(e)
148+
149+
resp = a.post(e)
150+
self.assertNotEqual(resp, True)
151+
self.assertFalse(resp)
152+
153+
self.assertFalse(a.disabled)
154+
155+
self.assertEqual(len(e.samples), 0)
156+
157+
self.assertEqual(mock_logging.exception.call_args_list[0][0][
158+
0], 'error posting payload to api ingest endpoint (%s): %s')
159+
129160
@mock.patch('netuitive.client.urllib2.urlopen')
130161
@mock.patch('netuitive.client.logging')
131162
def test_failure_general(self, mock_logging, mock_post):

0 commit comments

Comments
 (0)