2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

Adds callback for creation of an error log (#3136)

* Adds callback for creation of an error log

* Fix unit tests
This commit is contained in:
Oliver 2022-06-06 15:21:31 +10:00 committed by GitHub
parent a066fcc909
commit 92aa7adfec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 5 deletions

View File

@ -5,17 +5,21 @@ import os
import re import re
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.db.models.signals import pre_delete from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from error_report.models import Error
from mptt.exceptions import InvalidMove from mptt.exceptions import InvalidMove
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
import InvenTree.helpers
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeURLField
from InvenTree.validators import validate_tree_name from InvenTree.validators import validate_tree_name
@ -442,3 +446,37 @@ def before_delete_tree_item(sender, instance, using, **kwargs):
for child in instance.children.all(): for child in instance.children.all():
child.parent = instance.parent child.parent = instance.parent
child.save() child.save()
@receiver(post_save, sender=Error, dispatch_uid='error_post_save_notification')
def after_error_logged(sender, instance: Error, created: bool, **kwargs):
"""Callback when a server error is logged.
- Send a UI notification to all users with staff status
"""
if created:
try:
import common.notifications
users = get_user_model().objects.filter(is_staff=True)
context = {
'error': instance,
'name': _('Server Error'),
'message': _('An error has been logged by the server.'),
'link': InvenTree.helpers.construct_absolute_url(
reverse('admin:error_report_error_change', kwargs={'object_id': instance.pk})
)
}
common.notifications.trigger_notification(
instance,
'inventree.error_log',
context=context,
targets=users,
)
except Exception as exc:
"""We do not want to throw an exception while reporting an exception"""
logger.error(exc)

View File

@ -299,11 +299,12 @@ def trigger_notification(obj, category=None, obj_ref='pk', **kwargs):
delivery_methods = (delivery_methods - IGNORED_NOTIFICATION_CLS) delivery_methods = (delivery_methods - IGNORED_NOTIFICATION_CLS)
for method in delivery_methods: for method in delivery_methods:
logger.info(f"Triggering method '{method.METHOD_NAME}'") logger.info(f"Triggering notification method '{method.METHOD_NAME}'")
try: try:
deliver_notification(method, obj, category, targets, context) deliver_notification(method, obj, category, targets, context)
except NotImplementedError as error: except NotImplementedError as error:
raise error # Allow any single notification method to fail, without failing the others
logger.error(error)
except Exception as error: except Exception as error:
logger.error(error) logger.error(error)

View File

@ -93,7 +93,7 @@ class BulkNotificationMethodTests(BaseNotificationIntegrationTest):
def get_targets(self): def get_targets(self):
return [1, ] return [1, ]
with self.assertRaises(NotImplementedError): with self.assertLogs(logger='inventree', level='ERROR'):
self._notification_run(WrongImplementation) self._notification_run(WrongImplementation)
@ -115,7 +115,7 @@ class SingleNotificationMethodTests(BaseNotificationIntegrationTest):
def get_targets(self): def get_targets(self):
return [1, ] return [1, ]
with self.assertRaises(NotImplementedError): with self.assertLogs(logger='inventree', level='ERROR'):
self._notification_run(WrongImplementation) self._notification_run(WrongImplementation)
# A integration test for notifications is provided in test_part.PartNotificationTest # A integration test for notifications is provided in test_part.PartNotificationTest