Commit 60e9a77a by David Baumgold

Merge pull request #233 from edx/db/ajax-server-error

Make server errors return JSON if requested via AJAX
parents f9369b4f 7824b8c8
from django.http import HttpResponseServerError, HttpResponseNotFound from django.http import (HttpResponse, HttpResponseServerError,
HttpResponseNotFound)
from mitxmako.shortcuts import render_to_string, render_to_response from mitxmako.shortcuts import render_to_string, render_to_response
import functools
import json
__all__ = ['not_found', 'server_error', 'render_404', 'render_500'] __all__ = ['not_found', 'server_error', 'render_404', 'render_500']
def jsonable_error(status=500, message="The Studio servers encountered an error"):
"""
A decorator to make an error view return an JSON-formatted message if
it was requested via AJAX.
"""
def outer(func):
@functools.wraps(func)
def inner(request, *args, **kwargs):
if request.is_ajax():
content = json.dumps({"error": message})
return HttpResponse(content, content_type="application/json",
status=status)
else:
return func(request, *args, **kwargs)
return inner
return outer
@jsonable_error(404, "Resource not found")
def not_found(request): def not_found(request):
return render_to_response('error.html', {'error': '404'}) return render_to_response('error.html', {'error': '404'})
@jsonable_error(500, "The Studio servers encountered an error")
def server_error(request): def server_error(request):
return render_to_response('error.html', {'error': '500'}) return render_to_response('error.html', {'error': '500'})
@jsonable_error(404, "Resource not found")
def render_404(request): def render_404(request):
return HttpResponseNotFound(render_to_string('404.html', {})) return HttpResponseNotFound(render_to_string('404.html', {}))
@jsonable_error(500, "The Studio servers encountered an error")
def render_500(request): def render_500(request):
return HttpResponseServerError(render_to_string('500.html', {})) return HttpResponseServerError(render_to_string('500.html', {}))
...@@ -19,12 +19,15 @@ $ -> ...@@ -19,12 +19,15 @@ $ ->
if ajaxSettings.notifyOnError is false if ajaxSettings.notifyOnError is false
return return
if jqXHR.responseText if jqXHR.responseText
try
message = JSON.parse(jqXHR.responseText).error
catch error
message = _.str.truncate(jqXHR.responseText, 300) message = _.str.truncate(jqXHR.responseText, 300)
else else
message = gettext("This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.") message = gettext("This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.")
msg = new CMS.Views.Notification.Error( msg = new CMS.Views.Notification.Error(
"title": gettext("Studio's having trouble saving your work") "title": gettext("Studio's having trouble saving your work")
"message": message "message": message
) )
msg.show() msg.show()
......
...@@ -4,7 +4,10 @@ import sys ...@@ -4,7 +4,10 @@ import sys
from django.conf import settings from django.conf import settings
from django.core.validators import ValidationError, validate_email from django.core.validators import ValidationError, validate_email
from django.http import Http404, HttpResponse, HttpResponseNotAllowed from django.views.decorators.csrf import requires_csrf_token
from django.views.defaults import server_error
from django.http import (Http404, HttpResponse, HttpResponseNotAllowed,
HttpResponseServerError)
from dogapi import dog_stats_api from dogapi import dog_stats_api
from mitxmako.shortcuts import render_to_response from mitxmako.shortcuts import render_to_response
import zendesk import zendesk
...@@ -16,6 +19,19 @@ import track.views ...@@ -16,6 +19,19 @@ import track.views
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@requires_csrf_token
def jsonable_server_error(request, template_name='500.html'):
"""
500 error handler that serves JSON on an AJAX request, and proxies
to the Django default `server_error` view otherwise.
"""
if request.is_ajax():
msg = {"error": "The edX servers encountered an error"}
return HttpResponseServerError(json.dumps(msg))
else:
return server_error(request, template_name=template_name)
def calculate(request): def calculate(request):
''' Calculator in footer of every page. ''' ''' Calculator in footer of every page. '''
equation = request.GET['equation'] equation = request.GET['equation']
...@@ -228,4 +244,3 @@ def accepts(request, media_type): ...@@ -228,4 +244,3 @@ def accepts(request, media_type):
"""Return whether this request has an Accept header that matches type""" """Return whether this request has an Accept header that matches type"""
accept = parse_accept_header(request.META.get("HTTP_ACCEPT", "")) accept = parse_accept_header(request.META.get("HTTP_ACCEPT", ""))
return media_type in [t for (t, p, q) in accept] return media_type in [t for (t, p, q) in accept]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment