From becade1c9b5cf09923bf4cb3b287143b924003c3 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 7 Mar 2019 20:08:29 +0100 Subject: [PATCH 2/3] base: use deferrable to create ResourceLog objects (#31204) --- passerelle/base/models.py | 9 ++++++++- tests/test_proxylogger.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/passerelle/base/models.py b/passerelle/base/models.py index 2d8106d7..4885ca3a 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -34,10 +34,12 @@ from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from model_utils.managers import InheritanceManager as ModelUtilsInheritanceManager + import passerelle from passerelle.forms import GenericConnectorForm from passerelle.utils import ImportSiteError from passerelle.utils.api import endpoint +from passerelle.utils.defer import deferrable from passerelle.utils.jsonresponse import APIError from passerelle.utils.sftp import SFTP, SFTPField @@ -867,6 +869,11 @@ class ResourceLog(models.Model): extra = JSONField(verbose_name='extras', default=dict) transaction_id = models.UUIDField(null=True, db_index=True) + @classmethod + @deferrable + def safe_create(cls, **attr): + cls.objects.create(**attr) + class Meta: ordering = ('id',) permissions = (('see_resourcelog', 'Can see resource logs'),) @@ -1020,7 +1027,7 @@ class ProxyLogger: (exc_type, exc_value, dummy) = 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 c8205b1e..0442b411 100644 --- a/tests/test_proxylogger.py +++ b/tests/test_proxylogger.py @@ -389,3 +389,32 @@ def test_proxy_logger_bytes(db, connector): base_logger.debug('test', extra={'payload': b'\xff\xff'}) log = ResourceLog.objects.latest('id') assert log.extra == {'payload': '\\xff\\xff'} + + +def test_log_in_transaction(transactional_db, connector): + from django.db import transaction + + from passerelle.utils.defer import deferrable_scope + + qs = ResourceLog.objects.filter(message='coucou') + # without deferrable_scope 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 deferrable_scope logs are kept + try: + with deferrable_scope: + with transaction.atomic(): + connector.logger.info('coucou') + raise Exception + assert qs.exists() + except Exception: + pass + assert qs.exists() -- 2.36.1