Move @has_request_variables error responses to middleware

This will now allow us to use @has_request_variables on helper
functions.

(imported from commit 799d71477654eac7fd8192cfc5bb88b78053532d)
This commit is contained in:
Zev Benjamin
2012-12-19 14:19:46 -05:00
parent d179de07f6
commit bf5ce4783d
4 changed files with 45 additions and 4 deletions

View File

@@ -146,6 +146,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = (
# Our logging middleware should be the first middleware item.
'zephyr.middleware.LogRequests',
'zephyr.middleware.JsonErrorHandler',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',

View File

@@ -118,6 +118,27 @@ def internal_notify_view(view_func):
return view_func(request, *args, **kwargs)
return _wrapped_view_func
class RequestVariableMissingError(Exception):
def __init__(self, var_name):
self.var_name = var_name
def to_json_error_msg(self):
return "Missing '%s' argument" % (self.var_name,)
def __str__(self):
return self.to_json_error_msg()
class RequestVariableConversionError(Exception):
def __init__(self, var_name, bad_value):
self.var_name = var_name
self.bad_value = bad_value
def to_json_error_msg(self):
return "Bad value for '%s': %s" % (self.var_name, self.bad_value)
def __str__(self):
return self.to_json_error_msg()
# Used in conjunction with @has_request_variables, below
class POST(object):
# NotSpecified is a sentinel value for determining whether a
@@ -195,7 +216,7 @@ def has_request_variables(view_func):
val = request.POST[param.post_var_name]
except KeyError:
if param.default is POST.NotSpecified:
return json_error("Missing '%s' argument" % (param.post_var_name,))
raise RequestVariableMissingError(param.post_var_name)
val = param.default
default_assigned = True
@@ -203,8 +224,7 @@ def has_request_variables(view_func):
try:
val = param.converter(val)
except:
return json_error("Bad value for '%s': %s"
% (param.post_var_name, val))
raise RequestVariableConversionError(param.post_var_name, val)
kwargs[param.func_var_name] = val
return view_func(request, *args, **kwargs)

View File

@@ -1,3 +1,6 @@
from decorator import RequestVariableMissingError, RequestVariableConversionError
from zephyr.lib.response import json_error
import logging
import time
@@ -23,3 +26,9 @@ class LogRequests(object):
% (remote_ip, request.method, response.status_code,
time_delta, request.get_full_path()))
return response
class JsonErrorHandler(object):
def process_exception(self, request, exception):
if hasattr(exception, 'to_json_error_msg') and callable(exception.to_json_error_msg):
return json_error(exception.to_json_error_msg())
return None

View File

@@ -7,7 +7,7 @@ from django.db.models import Q
from zephyr.models import Message, UserProfile, Stream, Recipient, Subscription, \
filter_by_subscriptions, get_display_recipient, Realm, do_send_message, Client
from zephyr.views import json_get_updates, api_get_messages, gather_subscriptions
from zephyr.decorator import RespondAsynchronously
from zephyr.decorator import RespondAsynchronously, RequestVariableConversionError
from zephyr.lib.initial_password import initial_password, initial_api_key
import simplejson
@@ -723,6 +723,17 @@ class GetUpdatesTest(AuthedTestCase):
request = POSTRequestMock({}, user)
self.assertEquals(json_get_updates(request), RespondAsynchronously)
def test_bad_input(self):
"""
Specifying a bad value for 'pointer' should return an error
"""
self.login("hamlet@humbughq.com")
user = User.objects.get(email="hamlet@humbughq.com")
request = POSTRequestMock({'pointer': 'foo'}, user)
self.assertRaises(RequestVariableConversionError, json_get_updates, request)
class Runner(DjangoTestSuiteRunner):
option_list = (
optparse.make_option('--skip-generate',