From 742e579fa76387edc2dab504e2c8a356f6cfce5c Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 31 Jul 2022 02:10:49 +0200 Subject: [PATCH] [FR] Don't log 404 errors (#3436) * [FR] Don't log 404 errors Fixes #3418 * move ignored errors to settings * Add unittest * Add test for not ignored errors * Add check for manual logging --- InvenTree/InvenTree/exceptions.py | 6 +++++ InvenTree/InvenTree/middleware.py | 16 +++++++++++ InvenTree/InvenTree/settings.py | 14 +++++++--- InvenTree/InvenTree/test_middleware.py | 37 ++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/InvenTree/InvenTree/exceptions.py b/InvenTree/InvenTree/exceptions.py index ce79449c53..780359d88b 100644 --- a/InvenTree/InvenTree/exceptions.py +++ b/InvenTree/InvenTree/exceptions.py @@ -25,7 +25,13 @@ def log_error(path): Arguments: path: The 'path' (most likely a URL) associated with this error (optional) """ + kind, info, data = sys.exc_info() + + # Check if the eror is on the ignore list + if kind in settings.IGNORRED_ERRORS: + return + Error.objects.create( kind=kind.__name__, info=info, diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index c00d5dc5c5..1e282265c5 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -1,6 +1,7 @@ """Middleware for InvenTree.""" import logging +import sys from django.conf import settings from django.contrib.auth.middleware import PersistentRemoteUserMiddleware @@ -10,6 +11,7 @@ from django.urls import Resolver404, include, re_path, reverse_lazy from allauth_2fa.middleware import (AllauthTwoFactorMiddleware, BaseRequire2FAMiddleware) +from error_report.middleware import ExceptionProcessor from rest_framework.authtoken.models import Token from common.models import InvenTreeSetting @@ -145,3 +147,17 @@ class InvenTreeRemoteUserMiddleware(PersistentRemoteUserMiddleware): return return super().process_request(request) + + +class InvenTreeExceptionProcessor(ExceptionProcessor): + """Custom exception processor that respects blocked errors.""" + + def process_exception(self, request, exception): + """Check if kind is ignored before procesing.""" + kind, info, data = sys.exc_info() + + # Check if the eror is on the ignore list + if kind in settings.IGNORRED_ERRORS: + return + + return super().process_exception(request, exception) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 817294ef11..f9cf41deba 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -19,6 +19,7 @@ from pathlib import Path import django.conf.locale from django.core.files.storage import default_storage +from django.http import Http404 from django.utils.translation import gettext_lazy as _ import moneyed @@ -292,11 +293,9 @@ MIDDLEWARE = CONFIG.get('middleware', [ 'InvenTree.middleware.AuthRequiredMiddleware', 'InvenTree.middleware.Check2FAMiddleware', # Check if the user should be forced to use MFA 'maintenance_mode.middleware.MaintenanceModeMiddleware', + 'InvenTree.middleware.InvenTreeExceptionProcessor', # Error reporting ]) -# Error reporting middleware -MIDDLEWARE.append('error_report.middleware.ExceptionProcessor') - AUTHENTICATION_BACKENDS = CONFIG.get('authentication_backends', [ 'django.contrib.auth.backends.RemoteUserBackend', # proxy login 'django.contrib.auth.backends.ModelBackend', @@ -467,6 +466,10 @@ if db_engine in ['sqlite3', 'postgresql', 'mysql']: db_name = db_config['NAME'] db_host = db_config.get('HOST', "''") +if 'sqlite' in db_engine: + db_name = str(Path(db_name).resolve()) + db_config['NAME'] = db_name + logger.info(f"DB_ENGINE: {db_engine}") logger.info(f"DB_NAME: {db_name}") logger.info(f"DB_HOST: {db_host}") @@ -928,6 +931,11 @@ if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover for key, val in inventree_tags.items(): sentry_sdk.set_tag(f'inventree_{key}', val) +# In-database error logging +IGNORRED_ERRORS = [ + Http404 +] + # Maintenance mode MAINTENANCE_MODE_RETRY_AFTER = 60 MAINTENANCE_MODE_STATE_BACKEND = 'maintenance_mode.backends.DefaultStorageBackend' diff --git a/InvenTree/InvenTree/test_middleware.py b/InvenTree/InvenTree/test_middleware.py index 96748b00f1..5f9eb3b9c4 100644 --- a/InvenTree/InvenTree/test_middleware.py +++ b/InvenTree/InvenTree/test_middleware.py @@ -1,7 +1,12 @@ """Tests for middleware functions.""" +from django.conf import settings +from django.http import Http404 from django.urls import reverse +from error_report.models import Error + +from InvenTree.exceptions import log_error from InvenTree.helpers import InvenTreeTestCase @@ -58,3 +63,35 @@ class MiddlewareTests(InvenTreeTestCase): # should still fail without token self.check_path(reverse('settings.js'), 401) + + def test_error_exceptions(self): + """Test that ignored errors are not logged.""" + def check(excpected_nbr=0): + # Check that errors are empty + errors = Error.objects.all() + self.assertEqual(len(errors), excpected_nbr) + + # Test normal setup + check() + response = self.client.get(reverse('part-detail', kwargs={'pk': 9999})) + self.assertEqual(response.status_code, 404) + check() + + # Test manual logging + try: + raise Http404 + except Http404: + log_error('testpath') + + # Test setup without ignored errors + settings.IGNORRED_ERRORS = [] + response = self.client.get(reverse('part-detail', kwargs={'pk': 9999})) + self.assertEqual(response.status_code, 404) + check(1) + + # Test manual logging + try: + raise Http404 + except Http404: + log_error('testpath') + check(2)