Просмотр исходного кода

Fixes #23471: Don't report 404s to Sentry when replaced by an APPEND_SLASH redirect

Arthur 10 часов назад
Родитель
Сommit
3cd0bed3a2
3 измененных файлов с 38 добавлено и 4 удалено
  1. 10 0
      netbox/netbox/middleware.py
  2. 25 0
      netbox/netbox/tests/test_middleware.py
  3. 3 4
      netbox/netbox/views/errors.py

+ 10 - 0
netbox/netbox/middleware.py

@@ -48,6 +48,16 @@ class CommonMiddleware(DjangoCommonMiddleware):
             return False
         return super().should_redirect_with_slash(request)
 
+    def process_response(self, request, response):
+        response = super().process_response(request, response)
+
+        # Report 404s to Sentry only if they weren't replaced with an APPEND_SLASH redirect
+        if settings.SENTRY_ENABLED and response.status_code == 404 and getattr(request, '_sentry_report_404', False):
+            from sentry_sdk import capture_message
+            capture_message("Page not found", level="error")
+
+        return response
+
 
 class CoreMiddleware:
 

+ 25 - 0
netbox/netbox/tests/test_middleware.py

@@ -1,4 +1,5 @@
 import json
+import sys
 from contextlib import contextmanager
 from types import SimpleNamespace
 from unittest.mock import Mock, patch
@@ -156,3 +157,27 @@ class CoreMiddlewareTestCase(TestCase):
             response = self.process_internal_error(request, 'Simulated maintenance mode GraphQL error')
 
         self.assert_json_500_response(response)
+
+
+@override_settings(SENTRY_ENABLED=True)
+class SentryNotFoundReportingTestCase(TestCase):
+
+    def setUp(self):
+        super().setUp()
+        self.sentry_sdk = Mock()
+        patcher = patch.dict(sys.modules, {'sentry_sdk': self.sentry_sdk})
+        patcher.start()
+        self.addCleanup(patcher.stop)
+
+    def test_404_reported_to_sentry(self):
+        response = self.client.get('/nonexistent-path/')
+
+        self.assertEqual(response.status_code, 404)
+        self.sentry_sdk.capture_message.assert_called_once_with('Page not found', level='error')
+
+    def test_append_slash_redirect_not_reported_to_sentry(self):
+        response = self.client.get('/api/status')
+
+        self.assertEqual(response.status_code, 301)
+        self.assertEqual(response.headers['Location'], '/api/status/')
+        self.sentry_sdk.capture_message.assert_not_called()

+ 3 - 4
netbox/netbox/views/errors.py

@@ -31,11 +31,10 @@ class StaticMediaFailureView(View):
 
 def handler_404(request, exception):
     """
-    Wrap Django's default 404 handler to enable Sentry reporting.
+    Wrap Django's default 404 handler to enable Sentry reporting. The report is sent by CommonMiddleware
+    once the final response is known (it may be replaced with an APPEND_SLASH redirect).
     """
-    if settings.SENTRY_ENABLED:
-        from sentry_sdk import capture_message
-        capture_message("Page not found", level="error")
+    request._sentry_report_404 = True
 
     return page_not_found(request, exception)