From 20605be859972ed0a21a5adbd533affdb9ad8337 Mon Sep 17 00:00:00 2001 From: Graham Date: Mon, 6 Jul 2026 09:54:22 -0500 Subject: [PATCH] Fixes #22500: Use passed error kwarg in handle_rest_api_exception() (#22562) --- netbox/utilities/error_handlers.py | 17 +++++--- netbox/utilities/tests/test_error_handlers.py | 42 +++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 netbox/utilities/tests/test_error_handlers.py 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")