diff --git a/tests/test_logging.py b/tests/test_logging.py index 0d1082b..6d9f6cc 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -137,6 +137,7 @@ class LoggingTestCase(utils.TestCase): logfile = os.path.realpath(os.path.expanduser('~/.wakatime.log')) self.assertEquals(logfile, logging.getLogger('WakaTime').handlers[0].baseFilename) output = [u(' ').join(x) for x in logs.actual()] + expected = u('WakaTime WARNING Regex error (unbalanced parenthesis) for include pattern: \\(invalid regex)') if self.isPy35OrNewer: expected = u('WakaTime WARNING Regex error (unbalanced parenthesis at position 15) for include pattern: \\(invalid regex)') @@ -147,7 +148,7 @@ class LoggingTestCase(utils.TestCase): self.assertEquals(output[1], expected) self.assertEquals(output[2], u('WakaTime DEBUG Sending heartbeats to api at https://api.wakatime.com/api/v1/users/current/heartbeats.bulk')) self.assertIn('Python', output[3]) - self.assertIn('response_code', output[5]) + self.assertIn('response_code', output[4]) @log_capture() def test_exception_traceback_logged_in_debug_mode(self, logs): diff --git a/wakatime/api.py b/wakatime/api.py index a520959..99fa0b8 100644 --- a/wakatime/api.py +++ b/wakatime/api.py @@ -138,50 +138,47 @@ def send_heartbeats(heartbeats, args, configs, use_ntlm_proxy=False): else: code = response.status_code if response is not None else None content = response.text if response is not None else None - try: - results = response.json() if response is not None else [] - except: - if log.isEnabledFor(logging.DEBUG): - log.traceback(logging.WARNING) - results = [] - if code == requests.codes.created or code == requests.codes.accepted: - log.debug({ - 'response_code': code, - }) - - for i in range(len(results)): - if len(heartbeats) <= i: - log.debug('Results from server do not match heartbeats sent.') - break - - try: - c = results[i][1] - except: - c = 0 - try: - text = json.dumps(results[i][0]) - except: - if log.isEnabledFor(logging.DEBUG): - log.traceback(logging.WARNING) - text = '' - handle_result([heartbeats[i]], c, text, args, configs) + if _success(code): + results = _get_results(response) + _process_server_results(heartbeats, code, content, results, args, configs) session_cache.save(session) return SUCCESS if should_try_ntlm: return send_heartbeats(heartbeats, args, configs, use_ntlm_proxy=True) - else: - handle_result(heartbeats, code, content, args, configs) + + _handle_unsent_heartbeats(heartbeats, code, content, args, configs) session_cache.delete() return AUTH_ERROR if code == 401 else API_ERROR -def handle_result(h, code, content, args, configs): - if code == requests.codes.created or code == requests.codes.accepted: - return +def _process_server_results(heartbeats, code, content, results, args, configs): + log.debug({ + 'response_code': code, + }) + for i in range(len(results)): + if len(heartbeats) <= i: + log.debug('Results from server do not match heartbeats sent.') + break + + try: + c = results[i][1] + except: + c = 0 + try: + text = json.dumps(results[i][0]) + except: + if log.isEnabledFor(logging.DEBUG): + log.traceback(logging.WARNING) + text = '' + if not _success(c): + _handle_unsent_heartbeats([heartbeats[i]], c, text, args, configs) + + +def _handle_unsent_heartbeats(heartbeats, code, content, args, configs): if args.offline: if code == 400: log.error({ @@ -195,9 +192,24 @@ def handle_result(h, code, content, args, configs): 'response_content': content, }) queue = Queue(args, configs) - queue.push_many(h) + queue.push_many(heartbeats) else: log.error({ 'response_code': code, 'response_content': content, }) + + +def _get_results(response): + results = [] + if response is not None: + try: + results = response.json() + except: + if log.isEnabledFor(logging.DEBUG): + log.traceback(logging.WARNING) + return results + + +def _success(code): + return code == requests.codes.created or code == requests.codes.accepted