tornado: Use a machine-readable error code when an event queue is gone.

This fixes the original issue that #5598 was the root cause of; when
the user returns to a Zulip browser tab after they've been idle past
the timeout (10 min, per IDLE_EVENT_QUEUE_TIMEOUT_SECS), we now
correctly reload the page even if they're using Zulip in German or
another non-English language where we have a translation for the
relevant error message.
This commit is contained in:
Greg Price
2017-07-20 17:20:31 -07:00
committed by Tim Abbott
parent 45b718a2a2
commit 709c3b50fc
6 changed files with 27 additions and 4 deletions

View File

@@ -188,7 +188,7 @@ function get_events(options) {
// If we're old enough that our message queue has been // If we're old enough that our message queue has been
// garbage collected, immediately reload. // garbage collected, immediately reload.
if ((xhr.status === 400) && if ((xhr.status === 400) &&
(JSON.parse(xhr.responseText).msg.indexOf("Bad event queue id") !== -1)) { (JSON.parse(xhr.responseText).code === 'BAD_EVENT_QUEUE_ID')) {
page_params.event_queue_expired = true; page_params.event_queue_expired = true;
reload.initiate({immediate: true, reload.initiate({immediate: true,
save_pointer: false, save_pointer: false,

View File

@@ -35,6 +35,7 @@ class ErrorCode(AbstractEnum):
QUOTA_EXCEEDED = () QUOTA_EXCEEDED = ()
BAD_NARROW = () BAD_NARROW = ()
UNAUTHORIZED_PRINCIPAL = () UNAUTHORIZED_PRINCIPAL = ()
BAD_EVENT_QUEUE_ID = ()
class JsonableError(Exception): class JsonableError(Exception):
'''A standardized error format we can turn into a nice JSON HTTP response. '''A standardized error format we can turn into a nice JSON HTTP response.

View File

@@ -33,6 +33,7 @@ from zerver.lib.queue import queue_json_publish
from zerver.lib.request import JsonableError from zerver.lib.request import JsonableError
from zerver.lib.timestamp import timestamp_to_datetime from zerver.lib.timestamp import timestamp_to_datetime
from zerver.tornado.descriptors import clear_descriptor_by_handler_id, set_descriptor_by_handler_id from zerver.tornado.descriptors import clear_descriptor_by_handler_id, set_descriptor_by_handler_id
from zerver.tornado.exceptions import BadEventQueueIdError
import copy import copy
import six import six
@@ -513,7 +514,7 @@ def fetch_events(query):
raise JsonableError(_("Missing 'last_event_id' argument")) raise JsonableError(_("Missing 'last_event_id' argument"))
client = get_client_descriptor(queue_id) client = get_client_descriptor(queue_id)
if client is None: if client is None:
raise JsonableError(_("Bad event queue id: %s") % (queue_id,)) raise BadEventQueueIdError(queue_id)
if user_profile_id != client.user_profile_id: if user_profile_id != client.user_profile_id:
raise JsonableError(_("You are not authorized to get events from this queue")) raise JsonableError(_("You are not authorized to get events from this queue"))
client.event_queue.prune(last_event_id) client.event_queue.prune(last_event_id)

View File

@@ -0,0 +1,19 @@
from __future__ import absolute_import
from typing import Text
from django.utils.translation import ugettext as _
from zerver.lib.exceptions import JsonableError, ErrorCode
class BadEventQueueIdError(JsonableError):
code = ErrorCode.BAD_EVENT_QUEUE_ID
data_fields = ['queue_id']
def __init__(self, queue_id):
# type: (Text) -> None
self.queue_id = queue_id # type: Text
@staticmethod
def msg_format():
# type: () -> Text
return _("Bad event queue id: {queue_id}")

View File

@@ -31,6 +31,7 @@ from zerver.middleware import record_request_start_data, record_request_stop_dat
from zerver.lib.redis_utils import get_redis_client from zerver.lib.redis_utils import get_redis_client
from zerver.lib.sessions import get_session_user from zerver.lib.sessions import get_session_user
from zerver.tornado.event_queue import get_client_descriptor from zerver.tornado.event_queue import get_client_descriptor
from zerver.tornado.exceptions import BadEventQueueIdError
logger = logging.getLogger('zulip.socket') logger = logging.getLogger('zulip.socket')
@@ -137,7 +138,7 @@ class SocketConnection(sockjs.tornado.SockJSConnection):
queue_id = msg['request']['queue_id'] queue_id = msg['request']['queue_id']
client = get_client_descriptor(queue_id) client = get_client_descriptor(queue_id)
if client is None: if client is None:
raise JsonableError(_('Bad event queue id: %s') % (queue_id,)) raise BadEventQueueIdError(queue_id)
if user_profile.id != client.user_profile_id: if user_profile.id != client.user_profile_id:
raise JsonableError(_("You are not the owner of the queue with id '%s'") % (queue_id,)) raise JsonableError(_("You are not the owner of the queue with id '%s'") % (queue_id,))

View File

@@ -13,6 +13,7 @@ from zerver.lib.response import json_success, json_error, json_response_from_err
from zerver.lib.validator import check_bool, check_list, check_string from zerver.lib.validator import check_bool, check_list, check_string
from zerver.tornado.event_queue import get_client_descriptor, \ from zerver.tornado.event_queue import get_client_descriptor, \
process_notification, fetch_events process_notification, fetch_events
from zerver.tornado.exceptions import BadEventQueueIdError
from django.core.handlers.base import BaseHandler from django.core.handlers.base import BaseHandler
from typing import Union, Optional, Iterable, Sequence, List, Text from typing import Union, Optional, Iterable, Sequence, List, Text
@@ -30,7 +31,7 @@ def cleanup_event_queue(request, user_profile, queue_id=REQ()):
# type: (HttpRequest, UserProfile, Text) -> HttpResponse # type: (HttpRequest, UserProfile, Text) -> HttpResponse
client = get_client_descriptor(str(queue_id)) client = get_client_descriptor(str(queue_id))
if client is None: if client is None:
return json_error(_("Bad event queue id: %s") % (queue_id,)) return json_response_from_error(BadEventQueueIdError(queue_id))
if user_profile.id != client.user_profile_id: if user_profile.id != client.user_profile_id:
return json_error(_("You are not authorized to access this queue")) return json_error(_("You are not authorized to access this queue"))
request._log_data['extra'] = "[%s]" % (queue_id,) request._log_data['extra'] = "[%s]" % (queue_id,)