From 5b06e48f3f688f2d0aaad45fe9a2e249181847d7 Mon Sep 17 00:00:00 2001 From: FELIX CHERUIYOT Date: Tue, 14 Mar 2023 10:08:42 +0300 Subject: [PATCH 1/2] Implemented CRUD_EVENT_NO_CHANGED_FIELDS_SKIP I experienced issues with replicas when pre_save is used. To avoid this issues, I'd like to silence pre_saves. I saw we have the flag CRUD_EVENT_NO_CHANGED_FIELDS_SKIP already in documentation but not implemented it. Please let me know if this fix implements CRUD_EVENT_NO_CHANGED_FIELDS_SKIP as it was intended. Thanks --- easyaudit/signals/model_signals.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index a76af3f0..33c5e5d1 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -18,7 +18,7 @@ from easyaudit.models import CRUDEvent from easyaudit.settings import REGISTERED_CLASSES, UNREGISTERED_CLASSES, \ WATCH_MODEL_EVENTS, CRUD_DIFFERENCE_CALLBACKS, LOGGING_BACKEND, \ - DATABASE_ALIAS + DATABASE_ALIAS, CRUD_EVENT_NO_CHANGED_FIELDS_SKIP from easyaudit.utils import get_m2m_field_name, model_delta logger = logging.getLogger(__name__) @@ -73,6 +73,9 @@ def pre_save(sender, instance, raw, using, update_fields, **kwargs): try: if not should_audit(instance): return False + + if CRUD_EVENT_NO_CHANGED_FIELDS_SKIP: + return with transaction.atomic(using=using): try: From 6190643fc7f577b0a57217888ee860bea701d4ae Mon Sep 17 00:00:00 2001 From: FELIX CHERUIYOT Date: Thu, 26 Jun 2025 08:13:04 +0000 Subject: [PATCH 2/2] Fix crud exception issues and prevent propagation of exceptions --- easyaudit/backends.py | 18 +++++++++++--- easyaudit/signals/model_signals.py | 38 ++++++++++++++++++------------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/easyaudit/backends.py b/easyaudit/backends.py index b80c7243..d7be40a0 100644 --- a/easyaudit/backends.py +++ b/easyaudit/backends.py @@ -7,10 +7,22 @@ class ModelBackend: def request(self, request_info): - return RequestEvent.objects.create(**request_info) + try: + return RequestEvent.objects.create(**request_info) + except Exception as e: + logger.error(f"Error creating RequestEvent: {e}") + return None def crud(self, crud_info): - return CRUDEvent.objects.create(**crud_info) + try: + return CRUDEvent.objects.create(**crud_info) + except Exception as e: + logger.error(f"Error creating CRUDEvent: {e}") + return None def login(self, login_info): - return LoginEvent.objects.create(**login_info) \ No newline at end of file + try: + return LoginEvent.objects.create(**login_info) + except Exception as e: + logger.error(f"Error creating LoginEvent: {e}") + return None \ No newline at end of file diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index 33c5e5d1..d40fa38a 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -1,6 +1,7 @@ import json import logging +from django.db.utils import OperationalError from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser @@ -125,9 +126,9 @@ def crud_flow(): }) except Exception as e: try: - logger.exception( + logger.error( "easy audit had a pre_save exception on CRUDEvent creation. instance: {}, instance pk: {}".format( - instance, instance.pk)) + instance, instance.pk), exc_info=True) except Exception: pass if getattr(settings, "TEST", False): @@ -135,7 +136,7 @@ def crud_flow(): else: transaction.on_commit(crud_flow, using=using) except Exception: - logger.exception('easy audit had a pre-save exception.') + logger.error('easy audit had a pre-save exception.', exc_info=True) def post_save(sender, instance, created, raw, using, update_fields, **kwargs): @@ -184,17 +185,20 @@ def crud_flow(): }) except Exception as e: try: - logger.exception( + logger.error( "easy audit had a post_save exception on CRUDEvent creation. instance: {}, instance pk: {}".format( - instance, instance.pk)) + instance, instance.pk), exc_info=True) except Exception: pass if getattr(settings, "TEST", False): crud_flow() else: transaction.on_commit(crud_flow, using=using) - except Exception: - logger.exception('easy audit had a post-save exception.') + + except OperationalError as ex: + logger.error(f'Easy audit had a post-save OperationalError. {ex}', exc_info=True) + except Exception as ex: + logger.error(f'Easy audit had a post-save exception. {ex}', exc_info=True) def _m2m_rev_field_name(model1, model2): @@ -282,9 +286,9 @@ def crud_flow(): }) except Exception as e: try: - logger.exception( + logger.error( "easy audit had a m2m_changed exception on CRUDEvent creation. instance: {}, instance pk: {}".format( - instance, instance.pk)) + instance, instance.pk), exc_info=True) except Exception: pass @@ -292,8 +296,10 @@ def crud_flow(): crud_flow() else: transaction.on_commit(crud_flow, using=using) - except Exception: - logger.exception('easy audit had an m2m-changed exception.') + except OperationalError as ex: + logger.error(f'Easy audit had a m2m-changed OperationalError. {ex}', exc_info=True) + except Exception as ex: + logger.error(f'Easy audit had a m2m-changed exception. {ex}', exc_info=True) def post_delete(sender, instance, using, **kwargs): @@ -330,9 +336,9 @@ def crud_flow(): except Exception as e: try: - logger.exception( + logger.error( "easy audit had a post_delete exception on CRUDEvent creation. instance: {}, instance pk: {}".format( - instance, instance.pk)) + instance, instance.pk), exc_info=True) except Exception: pass @@ -340,8 +346,10 @@ def crud_flow(): crud_flow() else: transaction.on_commit(crud_flow, using=using) - except Exception: - logger.exception('easy audit had a post-delete exception.') + except OperationalError as ex: + logger.error(f'Easy audit had a post-delete OperationalError. {ex}', exc_info=True) + except Exception as ex: + logger.error(f'Easy audit had a post-delete exception. {ex}', exc_info=True) if WATCH_MODEL_EVENTS: