exceptionhandler.py 3.0 KB

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