From 4b1facb9059d2c81162406099e4de0d1e704904d 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 | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/passerelle/base/models.py b/passerelle/base/models.py index c35f9445..884124ca 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -35,9 +35,11 @@ from django.contrib.contenttypes import fields from model_utils.managers import InheritanceManager as ModelUtilsInheritanceManager + import passerelle from passerelle.forms import GenericConnectorForm from passerelle.utils.api import endpoint +from passerelle.utils.defer import deferrable from passerelle.utils.jsonresponse import APIError from passerelle.utils.sftp import SFTPField, SFTP @@ -844,6 +846,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'),) @@ -969,7 +976,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 af61769a..ddbf4637 100644 --- a/tests/test_proxylogger.py +++ b/tests/test_proxylogger.py @@ -383,3 +383,31 @@ def test_logged_requests_and_responses_max_size(app, db, monkeypatch, settings): assert ResourceLog.objects.all()[1].extra.get('response_content') == '\'{"service_reply_var": "33\'' else: assert ResourceLog.objects.all()[1].extra.get('response_content') == 'b\'{"service_reply_var": "33\'' + + +def test_log_in_transaction(transactional_db, connector): + from passerelle.utils.defer import deferrable_barrier + from django.db import transaction + + qs = ResourceLog.objects.filter(message='coucou') + # without deferrable_barrier 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_barrier logs are kept + try: + with deferrable_barrier: + with transaction.atomic(): + connector.logger.info('coucou') + raise Exception + assert qs.exists() + except Exception: + pass + assert qs.exists() -- 2.31.1