Coverage for utilities/error_handlers.py: 44%

35 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1import platform 

2import sys 

3 

4from django.conf import settings 

5from django.contrib import messages 

6from django.db.models import ProtectedError, RestrictedError 

7from django.http import JsonResponse 

8from django.utils.html import escape 

9from django.utils.safestring import mark_safe 

10from django.utils.translation import gettext_lazy as _ 

11from rest_framework import status 

12 

13__all__ = ( 

14 'handle_protectederror', 

15 'handle_rest_api_exception', 

16) 

17 

18 

19def handle_protectederror(obj_list, request, e): 

20 """ 

21 Generate a user-friendly error message in response to a ProtectedError or RestrictedError exception. 

22 """ 

23 if type(e) is ProtectedError: 

24 protected_objects = list(e.protected_objects) 

25 elif type(e) is RestrictedError: 

26 protected_objects = list(e.restricted_objects) 

27 else: 

28 raise e 

29 

30 # Formulate the error message 

31 err_message = _('Unable to delete <strong>{objects}</strong>. {count} dependent objects were found: ').format( 

32 objects=', '.join(escape(obj) for obj in obj_list), 

33 count=len(protected_objects) if len(protected_objects) <= 50 else _('More than 50'), 

34 ) 

35 

36 # Append dependent objects to error message 

37 dependent_objects = [] 

38 for dependent in protected_objects[:50]: 

39 if hasattr(dependent, 'get_absolute_url'): 

40 dependent_objects.append(f'<a href="{dependent.get_absolute_url()}">{escape(dependent)}</a>') 

41 else: 

42 dependent_objects.append(escape(str(dependent))) 

43 err_message += ', '.join(dependent_objects) 

44 

45 messages.error(request, mark_safe(err_message)) 

46 

47 

48def handle_rest_api_exception(request, *args, **kwargs): 

49 """ 

50 Handle exceptions and return a useful error message for REST API requests. 

51 """ 

52 if 'error' in kwargs: 52 ↛ 53line 52 didn't jump to line 53 because the condition on line 52 was never true

53 error_message = str(kwargs['error']) 

54 type_, __ = sys.exc_info()[:2] 

55 exception_name = type_.__name__ if type_ else 'Exception' 

56 else: 

57 type_, error = sys.exc_info()[:2] 

58 error_message = str(error) 

59 exception_name = type_.__name__ 

60 data = { 

61 'error': error_message, 

62 'exception': exception_name, 

63 'netbox_version': settings.RELEASE.full_version, 

64 'python_version': platform.python_version(), 

65 } 

66 return JsonResponse(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)