Skip to content

Commit 648642b

Browse files
committed
Fix #181: return failed request IDs on 500/batch errors
* rework error processing logic to know about batch errors specifically. * count batch error actions as failed actions.
1 parent efba51e commit 648642b

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

user_sync/connector/umapi.py

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -302,46 +302,53 @@ def _execute_action(self, action):
302302
'''
303303
:type action: umapi_client.UserAction
304304
'''
305-
sent = 0
306305
try:
307306
_, sent, _ = self.connection.execute_single(action)
308307
except umapi_client.BatchError as e:
309-
self.logger.critical("Unexpected response! Actions may have failed: %s", e)
310-
sent = e.statistics[1]
311-
finally:
308+
self.process_sent_items(e.statistics[1], e)
309+
else:
312310
self.process_sent_items(sent)
313311

314-
def process_sent_items(self, total_sent):
315-
if (total_sent > 0):
316-
sent_items = self.items[0:total_sent]
317-
self.items = self.items[total_sent:]
318-
for sent_item in sent_items:
319-
action = sent_item['action']
320-
action_errors = action.execution_errors()
321-
is_success = not action_errors or len(action_errors) == 0
322-
323-
if (not is_success):
324-
self.error_count += 1
325-
for error in action_errors:
326-
self.logger.error('Error in requestID: %s (User: %s, Command: %s): code: "%s" message: "%s"',
327-
action.frame.get("requestID"),
328-
error.get("target", "<Unknown>"), error.get("command", "<Unknown>"),
329-
error.get('errorCode', "<None>"), error.get('message', "<None>"))
330-
331-
item_callback = sent_item['callback']
332-
if (callable(item_callback)):
333-
item_callback({
334-
"action": action,
335-
"is_success": is_success,
336-
"errors": action_errors
337-
})
338-
339312
def flush(self):
340-
sent = 0
341313
try:
342314
_, sent, _ = self.connection.execute_queued()
343315
except umapi_client.BatchError as e:
344-
self.logger.critical("Unexpected response! Actions may have failed: %s", e)
345-
sent = e.statistics[1]
346-
finally:
316+
self.process_sent_items(e.statistics[1], e)
317+
else:
347318
self.process_sent_items(sent)
319+
320+
def process_sent_items(self, total_sent, batch_error=None):
321+
'''
322+
Note items as sent, log any processing errors, and invoke any callbacks
323+
:param total_sent: number of sent items from queue, must be >= 0
324+
:param batch_error: a batch-level error that affected all items, if there was one
325+
:return:
326+
'''
327+
# update queue
328+
sent_items, self.items = self.items[:total_sent], self.items[total_sent:]
329+
330+
# collect sent actions, their errors, their callbacks
331+
details = [(item['action'], item['action'].execution_errors(), item['callback']) for item in sent_items]
332+
333+
# log errors
334+
if batch_error:
335+
request_ids = str([action.frame.get("requestID") for action, _, _ in details])
336+
self.logger.critical("Unexpected response! Sent actions %s may have failed: %s", request_ids, batch_error)
337+
self.error_count += total_sent
338+
else:
339+
for action, errors, _ in details:
340+
if errors:
341+
self.error_count += 1
342+
for error in errors:
343+
self.logger.error('Error in requestID: %s (User: %s, Command: %s): code: "%s" message: "%s"',
344+
action.frame.get("requestID"),
345+
error.get("target", "<Unknown>"), error.get("command", "<Unknown>"),
346+
error.get('errorCode', "<None>"), error.get('message', "<None>"))
347+
# invoke callbacks
348+
for action, errors, callback in details:
349+
if (callable(callback)):
350+
callback({
351+
"action": action,
352+
"is_success": not batch_error and not errors,
353+
"errors": batch_error or errors
354+
})

0 commit comments

Comments
 (0)