From c25e8bc5dc01a09acbbf33eaf39b4eaa38ef5721 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 7 Mar 2019 20:08:29 +0100 Subject: [PATCH 3/4] base: use deferrable to create ResourceLog objects (#31204) --- passerelle/base/models.py | 8 +++++++- tests/test_proxylogger.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/passerelle/base/models.py b/passerelle/base/models.py index 6f22d4a..1e522d4 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -31,6 +31,7 @@ from model_utils.managers import InheritanceManager as ModelUtilsInheritanceMana import jsonfield +from passerelle.utils.defer import deferrable import passerelle import requests @@ -592,6 +593,11 @@ class ResourceLog(models.Model): message = models.TextField(max_length=2048, verbose_name='message') extra = jsonfield.JSONField(verbose_name='extras', default={}) + @classmethod + @deferrable + def safe_create(cls, **attr): + cls.objects.create(**attr) + class Meta: permissions = ( ('view_resourcelog', 'Can view resource logs'), @@ -686,7 +692,7 @@ class ProxyLogger(object): (exc_type, exc_value, tb) = sys.exc_info() attr['extra']['error_summary'] = traceback.format_exception_only(exc_type, exc_value) - ResourceLog.objects.create(**attr) + ResourceLog.safe_create(**attr) admins = settings.ADMINS logging_parameters = self.connector.logging_parameters diff --git a/tests/test_proxylogger.py b/tests/test_proxylogger.py index f67b672..4369737 100644 --- a/tests/test_proxylogger.py +++ b/tests/test_proxylogger.py @@ -83,3 +83,31 @@ def test_log_on_connector_availability_change(db, connector): assert len(ResourceLog.objects.all()) == 3 assert ResourceLog.objects.all()[2].level == 'info' assert ResourceLog.objects.all()[2].message == u'connector "éléphant" (Feed) is back up' + + +def test_log_in_transaction(transactional_db, connector): + from passerelle.utils.defer import deferred + from django.db import transaction + + qs = ResourceLog.objects.filter(message='coucou') + # without deferred logs are lost + assert not qs.exists() + try: + with transaction.atomic(): + connector.logger.info('coucou') + raise Exception + assert qs.exists() + except Exception: + pass + assert not qs.exists() + + # with deferred logs are kept + try: + with deferred: + with transaction.atomic(): + connector.logger.info('coucou') + raise Exception + assert qs.exists() + except Exception: + pass + assert qs.exists() -- 2.20.1