diff --git a/cms/djangoapps/contentstore/views/error.py b/cms/djangoapps/contentstore/views/error.py index e1f1d6b21e..755417bda4 100644 --- a/cms/djangoapps/contentstore/views/error.py +++ b/cms/djangoapps/contentstore/views/error.py @@ -6,6 +6,7 @@ from django.http import HttpResponse, HttpResponseNotFound, HttpResponseServerEr from edxmako.shortcuts import render_to_response, render_to_string from openedx.core.djangolib.js_utils import dump_js_escaped_json +from util.views import fix_crum_request __all__ = ['not_found', 'server_error', 'render_404', 'render_500'] @@ -38,11 +39,13 @@ def server_error(request): return render_to_response('error.html', {'error': '500'}) +@fix_crum_request @jsonable_error(404, "Resource not found") def render_404(request): return HttpResponseNotFound(render_to_string('404.html', {}, request=request)) +@fix_crum_request @jsonable_error(500, "The Studio servers encountered an error") def render_500(request): return HttpResponseServerError(render_to_string('500.html', {}, request=request)) diff --git a/common/djangoapps/util/views.py b/common/djangoapps/util/views.py index 48763c00d9..cdf5f860a3 100644 --- a/common/djangoapps/util/views.py +++ b/common/djangoapps/util/views.py @@ -3,6 +3,7 @@ import logging import sys from functools import wraps from smtplib import SMTPException +import crum import zendesk from django.conf import settings @@ -87,6 +88,21 @@ def require_global_staff(func): return login_required(wrapped) +def fix_crum_request(func): + """ + A decorator that ensures that the 'crum' package (a middleware that stores and fetches the current request in + thread-local storage) can correctly fetch the current request. Under certain conditions, the current request cannot + be fetched by crum (e.g.: when HTTP errors are raised in our views via 'raise Http404', et. al.). This decorator + manually sets the current request for crum if it cannot be fetched. + """ + @wraps(func) + def wrapper(request, *args, **kwargs): + if not crum.get_current_request(): + crum.set_current_request(request=request) + return func(request, *args, **kwargs) + return wrapper + + @requires_csrf_token def jsonable_server_error(request, template_name='500.html'): """ diff --git a/lms/djangoapps/static_template_view/views.py b/lms/djangoapps/static_template_view/views.py index 0082c21186..5c1e2200db 100644 --- a/lms/djangoapps/static_template_view/views.py +++ b/lms/djangoapps/static_template_view/views.py @@ -13,6 +13,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie from edxmako.shortcuts import render_to_response, render_to_string from util.cache import cache_if_anonymous +from util.views import fix_crum_request valid_templates = [] @@ -74,9 +75,11 @@ def render_press_release(request, slug): return resp +@fix_crum_request def render_404(request): return HttpResponseNotFound(render_to_string('static_templates/404.html', {}, request=request)) +@fix_crum_request def render_500(request): return HttpResponseServerError(render_to_string('static_templates/server-error.html', {}, request=request))