diff --git a/netbox/utilities/error_handlers.py b/netbox/utilities/error_handlers.py
index 8c0dce57d..a7de246f7 100644
--- a/netbox/utilities/error_handlers.py
+++ b/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 {objects}. {count} dependent objects were found: ").format(
+ err_message = _('Unable to delete {objects}. {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(),
}
diff --git a/netbox/utilities/tests/test_error_handlers.py b/netbox/utilities/tests/test_error_handlers.py
new file mode 100644
index 000000000..13e41d75c
--- /dev/null
+++ b/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")