Commit ecf9923e by Greg Price

Return 404 instead of 500 for missing forum thread

Also show a more specific error message in the front end. This change
only has an effect if using cs_comments_service commit 1d71330 or later.
parent 3fd89a0d
...@@ -57,8 +57,13 @@ if Backbone? ...@@ -57,8 +57,13 @@ if Backbone?
@responses.add(data['content']['children']) @responses.add(data['content']['children'])
@renderResponseCountAndPagination(data['content']['resp_total']) @renderResponseCountAndPagination(data['content']['resp_total'])
@trigger "thread:responses:rendered" @trigger "thread:responses:rendered"
error: => error: (xhr) =>
if firstLoad if xhr.status == 404
DiscussionUtil.discussionAlert(
gettext("Sorry"),
gettext("The thread you selected has been deleted. Please select another thread.")
)
else if firstLoad
DiscussionUtil.discussionAlert( DiscussionUtil.discussionAlert(
gettext("Sorry"), gettext("Sorry"),
gettext("We had some trouble loading responses. Please reload the page.") gettext("We had some trouble loading responses. Please reload the page.")
......
import json import json
from django.http import Http404
from django.test.utils import override_settings from django.test.utils import override_settings
from django.test.client import Client, RequestFactory from django.test.client import Client, RequestFactory
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
...@@ -108,19 +109,22 @@ def make_mock_thread_data(text, thread_id, include_children): ...@@ -108,19 +109,22 @@ def make_mock_thread_data(text, thread_id, include_children):
def make_mock_request_impl(text, thread_id=None): def make_mock_request_impl(text, thread_id=None):
def mock_request_impl(*args, **kwargs): def mock_request_impl(*args, **kwargs):
url = args[1] url = args[1]
data = None
if url.endswith("threads"): if url.endswith("threads"):
data = { data = {
"collection": [make_mock_thread_data(text, "dummy_thread_id", False)] "collection": [make_mock_thread_data(text, "dummy_thread_id", False)]
} }
elif thread_id and url.endswith(thread_id): elif thread_id and url.endswith(thread_id):
data = make_mock_thread_data(text, thread_id, True) data = make_mock_thread_data(text, thread_id, True)
else: # user query elif "/users/" in url:
data = { data = {
"upvoted_ids": [], "upvoted_ids": [],
"downvoted_ids": [], "downvoted_ids": [],
"subscribed_thread_ids": [], "subscribed_thread_ids": [],
} }
return Mock(status_code=200, text=json.dumps(data), json=Mock(return_value=data)) if data:
return Mock(status_code=200, text=json.dumps(data), json=Mock(return_value=data))
return Mock(status_code=404)
return mock_request_impl return mock_request_impl
...@@ -233,6 +237,20 @@ class SingleThreadTestCase(ModuleStoreTestCase): ...@@ -233,6 +237,20 @@ class SingleThreadTestCase(ModuleStoreTestCase):
) )
self.assertEquals(response.status_code, 405) self.assertEquals(response.status_code, 405)
def test_not_found(self, mock_request):
request = RequestFactory().get("dummy_url")
request.user = self.student
# Mock request to return 404 for thread request
mock_request.side_effect = make_mock_request_impl("dummy", thread_id=None)
self.assertRaises(
Http404,
views.single_thread,
request,
self.course.id,
"test_discussion_id",
"test_thread_id"
)
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@patch('requests.request') @patch('requests.request')
......
...@@ -237,12 +237,17 @@ def single_thread(request, course_id, discussion_id, thread_id): ...@@ -237,12 +237,17 @@ def single_thread(request, course_id, discussion_id, thread_id):
# Currently, the front end always loads responses via AJAX, even for this # Currently, the front end always loads responses via AJAX, even for this
# page; it would be a nice optimization to avoid that extra round trip to # page; it would be a nice optimization to avoid that extra round trip to
# the comments service. # the comments service.
thread = cc.Thread.find(thread_id).retrieve( try:
recursive=request.is_ajax(), thread = cc.Thread.find(thread_id).retrieve(
user_id=request.user.id, recursive=request.is_ajax(),
response_skip=request.GET.get("resp_skip"), user_id=request.user.id,
response_limit=request.GET.get("resp_limit") response_skip=request.GET.get("resp_skip"),
) response_limit=request.GET.get("resp_limit")
)
except cc.utils.CommentClientRequestError as e:
if e.status_code == 404:
raise Http404
raise
if request.is_ajax(): if request.is_ajax():
with newrelic.agent.FunctionTrace(nr_transaction, "get_annotated_content_infos"): with newrelic.agent.FunctionTrace(nr_transaction, "get_annotated_content_infos"):
......
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