summaryrefslogtreecommitdiff
path: root/tuskar_ui
diff options
context:
space:
mode:
authorRadomir Dopieralski <openstack@sheep.art.pl>2014-03-05 11:36:17 +0100
committerRadomir Dopieralski <openstack@sheep.art.pl>2014-03-27 16:21:05 +0100
commit434955839b6d1d0913a8b786236b7ef3c7020c53 (patch)
tree1a6aa29f77e4bdf4531e1638046990c72e5ae419 /tuskar_ui
parent73d72ebd0ed9dd87a4adb083209eef88342e6557 (diff)
downloadtuskar-ui-434955839b6d1d0913a8b786236b7ef3c7020c53.tar.gz
Make @handle_errors support any kind of function
This hack lets the @handle_errors decorator be used on functions, methods, static methods and class methods, without having to worry about how many parameters the function takes, and whether there is "self" or not. Change-Id: Ie34d200939dbadae0771da893e563995cd3ecf45
Diffstat (limited to 'tuskar_ui')
-rw-r--r--tuskar_ui/handle_errors.py27
1 files changed, 21 insertions, 6 deletions
diff --git a/tuskar_ui/handle_errors.py b/tuskar_ui/handle_errors.py
index b1f14a3b..a505f4eb 100644
--- a/tuskar_ui/handle_errors.py
+++ b/tuskar_ui/handle_errors.py
@@ -13,18 +13,20 @@
# under the License.
import functools
+import inspect
import horizon.exceptions
-def handle_errors(error_message, error_default=None):
+def handle_errors(error_message, error_default=None, request_arg=None):
"""A decorator for adding default error handling to API calls.
It wraps the original method in a try-except block, with horizon's
error handling added.
- Note: it should only be used on methods that take request as the first
- (second after self or cls) argument.
+ Note: it should only be used on functions or methods that take request as
+ their argument (it has to be named "request", or ``request_arg`` has to be
+ provided, indicating which argument is the request).
The decorated method accepts a number of additional parameters:
@@ -35,18 +37,31 @@ def handle_errors(error_message, error_default=None):
:param _error_ignore: ignore known errors
"""
def decorator(func):
+ # XXX This is an ugly hack for finding the 'request' argument.
+ if request_arg is None:
+ for _request_arg, name in enumerate(inspect.getargspec(func).args):
+ if name == 'request':
+ break
+ else:
+ raise RuntimeError(
+ "The handle_errors decorator requires 'request' as "
+ "an argument of the function or method being decorated")
+ else:
+ _request_arg = request_arg
+
@functools.wraps(func)
- def wrapper(self, request, *args, **kwargs):
+ def wrapper(*args, **kwargs):
_error_handle = kwargs.pop('_error_handle', True)
_error_message = kwargs.pop('_error_message', error_message)
_error_default = kwargs.pop('_error_default', error_default)
_error_redirect = kwargs.pop('_error_redirect', None)
_error_ignore = kwargs.pop('_error_ignore', False)
if not _error_handle:
- return func(self, request, *args, **kwargs)
+ return func(*args, **kwargs)
try:
- return func(self, request, *args, **kwargs)
+ return func(*args, **kwargs)
except Exception:
+ request = args[_request_arg]
horizon.exceptions.handle(request, _error_message,
ignore=_error_ignore,
redirect=_error_redirect)