handle unknown exceptions from requests library by deleting cached session object

This commit is contained in:
Alan Hamlett 2016-07-06 23:07:55 +02:00
parent 5207dc68ee
commit a5933aa2a7
2 changed files with 51 additions and 1 deletions

View file

@ -5,14 +5,20 @@ from wakatime.main import execute
from wakatime.offlinequeue import Queue from wakatime.offlinequeue import Queue
from wakatime.packages import requests from wakatime.packages import requests
import logging
import os import os
import sqlite3 import sqlite3
import sys import sys
import tempfile import tempfile
import time import time
from testfixtures import log_capture
from wakatime.compat import u from wakatime.compat import u
from wakatime.packages.requests.models import Response from wakatime.packages.requests.models import Response
from . import utils from . import utils
try:
from mock import call
except ImportError:
from unittest.mock import call
class OfflineQueueTestCase(utils.TestCase): class OfflineQueueTestCase(utils.TestCase):
@ -170,3 +176,35 @@ class OfflineQueueTestCase(utils.TestCase):
db_file = queue.get_db_file() db_file = queue.get_db_file()
expected = os.path.join(os.path.expanduser('~'), '.wakatime.db') expected = os.path.join(os.path.expanduser('~'), '.wakatime.db')
self.assertEquals(db_file, expected) self.assertEquals(db_file, expected)
@log_capture()
def test_heartbeat_saved_when_requests_raises_exception(self, logs):
logging.disable(logging.NOTSET)
with tempfile.NamedTemporaryFile() as fh:
with utils.mock.patch('wakatime.offlinequeue.Queue.get_db_file') as mock_db_file:
mock_db_file.return_value = fh.name
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].side_effect = AttributeError("'Retry' object has no attribute 'history'")
now = u(int(time.time()))
entity = 'tests/samples/codefiles/twolinefile.txt'
config = 'tests/samples/configs/good_config.cfg'
args = ['--file', entity, '--config', config, '--time', now]
execute(args)
queue = Queue()
saved_heartbeat = queue.pop()
self.assertEquals(os.path.realpath(entity), saved_heartbeat['entity'])
self.assertEquals(sys.stdout.getvalue(), '')
self.assertEquals(sys.stderr.getvalue(), '')
output = [u(' ').join(x) for x in logs.actual()]
expected = u("AttributeError: \\'Retry\\' object has no attribute \\'history\\'")
self.assertIn(expected, output[0])
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
self.patched['wakatime.session_cache.SessionCache.delete'].assert_has_calls([call(), call()])
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()

View file

@ -187,7 +187,7 @@ def parseArguments():
# update args from configs # update args from configs
if not args.hostname: if not args.hostname:
if configs.has_option('settings', 'hostname'): if configs.has_option('settings', 'hostname'):
args.hostname = configs.get('settings', 'hostname') args.hostname = configs.get('settings', 'hostname')
if not args.key: if not args.key:
default_key = None default_key = None
if configs.has_option('settings', 'api_key'): if configs.has_option('settings', 'api_key'):
@ -388,6 +388,18 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
log.warn(exception_data) log.warn(exception_data)
else: else:
log.error(exception_data) log.error(exception_data)
except: # delete cached session when requests raises unknown exception
exception_data = {
sys.exc_info()[0].__name__: u(sys.exc_info()[1]),
'traceback': traceback.format_exc(),
}
if offline:
queue = Queue()
queue.push(data, json.dumps(stats), plugin)
log.warn(exception_data)
session_cache.delete()
else: else:
code = response.status_code if response is not None else None code = response.status_code if response is not None else None
content = response.text if response is not None else None content = response.text if response is not None else None