Skip to content

Commit

Permalink
Prevent log save failure to break API call
Browse files Browse the repository at this point in the history
This is a follow-up of the discussion in PR aschn#55.

If something is going wrong during log saving, we don't want
the API to fail and throw out an error to the end user.

To do this, silently swallow any exception throwed by save().

A test is provided to check that the response status_code of
the API is still 200 even in the event of a DB failure.
  • Loading branch information
François Voron committed Jul 11, 2017
1 parent e75bd8a commit 3405a20
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
6 changes: 5 additions & 1 deletion rest_framework_tracking/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ def finalize_response(self, request, response, *args, **kwargs):
self.request.log.response = response.rendered_content
self.request.log.status_code = response.status_code
self.request.log.response_ms = response_ms
self.request.log.save()
try:
self.request.log.save()
except:
# ensure that a DB error doesn't prevent API call to continue as expected
pass

# return
return response
Expand Down
11 changes: 6 additions & 5 deletions tests/test_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.contrib.auth.models import User
from django.utils.timezone import now
from flaky import flaky
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.test import APIRequestFactory, APITestCase
from rest_framework_tracking.models import APIRequestLog
Expand Down Expand Up @@ -254,9 +255,9 @@ def test_log_request_body_parse_error(self):
self.assertEqual(log.status_code, 400)
self.assertIn('parse error', log.response)

@mock.patch('rest_framework_tracking.mixins.APIRequestLog')
def test_does_not_crash_on_data_not_fitting_in_the_db(self, mock_apirequestlog):
mock_apirequestlog.objects = mock.MagicMock()
mock_apirequestlog.objects.create = mock.MagicMock(side_effect=Exception("integrity"))
self.client.get('/logging')
@mock.patch('rest_framework_tracking.models.APIRequestLog.save')
def test_log_doesnt_prevent_api_call_if_log_save_fails(self, mock_apirequestlog_save):
mock_apirequestlog_save.side_effect = Exception('db failure')
response = self.client.get('/logging')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(APIRequestLog.objects.all().count(), 0)

0 comments on commit 3405a20

Please sign in to comment.