exceptionhandler.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 social_core.exceptions import SocialAuthBaseException
  7. from social_core.utils import social_logger
  8. from . import errorpages
  9. from .exceptions import AjaxError, Banned, ExplicitFirstPage, OutdatedSlug
  10. HANDLED_EXCEPTIONS = (
  11. AjaxError,
  12. Banned,
  13. ExplicitFirstPage,
  14. Http404,
  15. OutdatedSlug,
  16. PermissionDenied,
  17. SocialAuthBaseException,
  18. )
  19. def is_misago_exception(exception):
  20. return isinstance(exception, HANDLED_EXCEPTIONS)
  21. def handle_ajax_error(request, exception):
  22. json = {
  23. 'is_error': 1,
  24. 'message': six.text_type(exception.message),
  25. }
  26. return JsonResponse(json, status=exception.code)
  27. def handle_banned_exception(request, exception):
  28. return errorpages.banned(request, exception)
  29. def handle_explicit_first_page_exception(request, exception):
  30. matched_url = request.resolver_match.url_name
  31. if request.resolver_match.namespace:
  32. matched_url = '%s:%s' % (request.resolver_match.namespace, matched_url)
  33. url_kwargs = request.resolver_match.kwargs
  34. del url_kwargs['page']
  35. new_url = reverse(matched_url, kwargs=url_kwargs)
  36. return HttpResponsePermanentRedirect(new_url)
  37. def handle_http404_exception(request, exception):
  38. return errorpages.page_not_found(request, exception)
  39. def handle_outdated_slug_exception(request, exception):
  40. view_name = request.resolver_match.view_name
  41. model = exception.args[0]
  42. url_kwargs = request.resolver_match.kwargs
  43. url_kwargs['slug'] = model.slug
  44. new_url = reverse(view_name, kwargs=url_kwargs)
  45. return HttpResponsePermanentRedirect(new_url)
  46. def handle_permission_denied_exception(request, exception):
  47. return errorpages.permission_denied(request, exception)
  48. def handle_social_auth_exception(request, exception):
  49. social_logger.error(exception)
  50. return errorpages.social_auth_failed(request, exception)
  51. EXCEPTION_HANDLERS = [
  52. (AjaxError, handle_ajax_error),
  53. (Banned, handle_banned_exception),
  54. (Http404, handle_http404_exception),
  55. (ExplicitFirstPage, handle_explicit_first_page_exception),
  56. (OutdatedSlug, handle_outdated_slug_exception),
  57. (PermissionDenied, handle_permission_denied_exception),
  58. (SocialAuthBaseException, handle_social_auth_exception),
  59. ]
  60. def get_exception_handler(exception):
  61. for exception_type, handler in EXCEPTION_HANDLERS:
  62. if isinstance(exception, exception_type):
  63. return handler
  64. else:
  65. raise ValueError("%s is not Misago exception" % exception.__class__.__name__)
  66. def handle_misago_exception(request, exception):
  67. handler = get_exception_handler(exception)
  68. return handler(request, exception)
  69. def handle_api_exception(exception, context):
  70. response = rest_exception_handler(exception, context)
  71. if response:
  72. if isinstance(exception, Banned):
  73. response.data['ban'] = exception.ban.get_serialized_message()
  74. elif isinstance(exception, PermissionDenied):
  75. try:
  76. response.data['detail'] = exception.args[0]
  77. except IndexError:
  78. pass
  79. return response
  80. else:
  81. return None