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
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
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.urls import reverse
from django.utils.translation import gettext_lazy as _
from error_report.models import Error
from mptt.exceptions import InvalidMove
from mptt.models import MPTTModel, TreeForeignKey
import InvenTree.helpers
from InvenTree.fields import InvenTreeURLField
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():
child.parent = instance.parent
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)
for method in delivery_methods:
logger.info(f"Triggering method '{method.METHOD_NAME}'")
logger.info(f"Triggering notification method '{method.METHOD_NAME}'")
try:
deliver_notification(method, obj, category, targets, context)
except NotImplementedError as error:
raise error
# Allow any single notification method to fail, without failing the others
logger.error(error)
except Exception as error:
logger.error(error)

View File

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