Browse Source

Fixes #22500: Use passed error kwarg in handle_rest_api_exception() (#22562)

Graham 18 hours ago
parent
commit
20605be859
2 changed files with 54 additions and 5 deletions
  1. 12 5
      netbox/utilities/error_handlers.py
  2. 42 0
      netbox/utilities/tests/test_error_handlers.py

+ 12 - 5
netbox/utilities/error_handlers.py

@@ -28,9 +28,9 @@ def handle_protectederror(obj_list, request, e):
         raise e
 
     # Formulate the error message
-    err_message = _("Unable to delete <strong>{objects}</strong>. {count} dependent objects were found: ").format(
+    err_message = _('Unable to delete <strong>{objects}</strong>. {count} dependent objects were found: ').format(
         objects=', '.join(escape(obj) for obj in obj_list),
-        count=len(protected_objects) if len(protected_objects) <= 50 else _('More than 50')
+        count=len(protected_objects) if len(protected_objects) <= 50 else _('More than 50'),
     )
 
     # Append dependent objects to error message
@@ -49,10 +49,17 @@ def handle_rest_api_exception(request, *args, **kwargs):
     """
     Handle exceptions and return a useful error message for REST API requests.
     """
-    type_, error = sys.exc_info()[:2]
+    if 'error' in kwargs:
+        error_message = str(kwargs['error'])
+        type_, __ = sys.exc_info()[:2]
+        exception_name = type_.__name__ if type_ else 'Exception'
+    else:
+        type_, error = sys.exc_info()[:2]
+        error_message = str(error)
+        exception_name = type_.__name__
     data = {
-        'error': str(error),
-        'exception': type_.__name__,
+        'error': error_message,
+        'exception': exception_name,
         'netbox_version': settings.RELEASE.full_version,
         'python_version': platform.python_version(),
     }

+ 42 - 0
netbox/utilities/tests/test_error_handlers.py

@@ -0,0 +1,42 @@
+import json
+
+from django.test import RequestFactory, TestCase
+
+from utilities.error_handlers import handle_rest_api_exception
+
+
+class HandleRestApiExceptionTestCase(TestCase):
+    """
+    Test handle_rest_api_exception() response formatting.
+    """
+
+    def setUp(self):
+        self.factory = RequestFactory()
+        self.request = self.factory.get('/api/test/')
+
+    def test_error_kwarg_used_when_provided(self):
+        """
+        When an error kwarg is passed, it should appear in the response body.
+        """
+        try:
+            raise ValueError("raw exception message")
+        except ValueError:
+            response = handle_rest_api_exception(self.request, error="custom error message")
+
+        data = json.loads(response.content)
+        self.assertEqual(response.status_code, 500)
+        self.assertEqual(data['error'], "custom error message")
+
+    def test_fallback_to_exc_info_when_no_kwarg(self):
+        """
+        When no error kwarg is passed, sys.exc_info() should be used.
+        """
+        try:
+            raise ValueError("raw exception message")
+        except ValueError:
+            response = handle_rest_api_exception(self.request)
+
+        data = json.loads(response.content)
+        self.assertEqual(response.status_code, 500)
+        self.assertEqual(data['error'], "raw exception message")
+        self.assertEqual(data['exception'], "ValueError")