exceptionhandler.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from rest_framework.views import exception_handler as rest_exception_handler
  2. from django.core.exceptions import PermissionDenied
  3. from django.http import Http404, HttpResponsePermanentRedirect, JsonResponse
  4. from django.urls import reverse
  5. from django.utils import six
  6. from . import errorpages
  7. from .exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
  8. HANDLED_EXCEPTIONS = (AjaxError, Banned, ExplicitFirstPage, Http404, OutdatedSlug, PermissionDenied)
  9. def is_misago_exception(exception):
  10. return exception.__class__ in HANDLED_EXCEPTIONS
  11. def handle_ajax_error(request, exception):
  12. json = {'is_error': 1, 'message': six.text_type(exception.message)}
  13. return JsonResponse(json, status=exception.code)
  14. def handle_banned_exception(request, exception):
  15. return errorpages.banned(request, exception.ban)
  16. def handle_explicit_first_page_exception(request, exception):
  17. matched_url = request.resolver_match.url_name
  18. if request.resolver_match.namespace:
  19. matched_url = '%s:%s' % (request.resolver_match.namespace, matched_url)
  20. url_kwargs = request.resolver_match.kwargs
  21. del url_kwargs['page']
  22. new_url = reverse(matched_url, kwargs=url_kwargs)
  23. return HttpResponsePermanentRedirect(new_url)
  24. def handle_http404_exception(request, exception):
  25. return errorpages.page_not_found(request)
  26. def handle_outdated_slug_exception(request, exception):
  27. view_name = request.resolver_match.view_name
  28. model = exception.args[0]
  29. url_kwargs = request.resolver_match.kwargs
  30. url_kwargs['slug'] = model.slug
  31. new_url = reverse(view_name, kwargs=url_kwargs)
  32. return HttpResponsePermanentRedirect(new_url)
  33. def handle_permission_denied_exception(request, exception):
  34. try:
  35. error_message = exception.args[0]
  36. except IndexError:
  37. error_message = None
  38. return errorpages.permission_denied(request, error_message)
  39. EXCEPTION_HANDLERS = ((AjaxError, handle_ajax_error),
  40. (Banned, handle_banned_exception),
  41. (Http404, handle_http404_exception),
  42. (ExplicitFirstPage, handle_explicit_first_page_exception),
  43. (OutdatedSlug, handle_outdated_slug_exception),
  44. (PermissionDenied, handle_permission_denied_exception), )
  45. def get_exception_handler(exception):
  46. for exception_type, handler in EXCEPTION_HANDLERS:
  47. if isinstance(exception, exception_type):
  48. return handler
  49. else:
  50. raise ValueError("%s is not Misago exception" % exception.__class__.__name__)
  51. def handle_misago_exception(request, exception):
  52. handler = get_exception_handler(exception)
  53. return handler(request, exception)
  54. def handle_api_exception(exception, context):
  55. response = rest_exception_handler(exception, context)
  56. if response:
  57. if isinstance(exception, Banned):
  58. response.data['ban'] = exception.ban.get_serialized_message()
  59. elif isinstance(exception, PermissionDenied):
  60. try:
  61. response.data['detail'] = exception.args[0]
  62. except IndexError:
  63. pass
  64. return response
  65. else:
  66. return None