Mercurial > kallithea
changeset 6376:dc94e662ee74
tg: refactor API JSON RPC error handling to prepare for TG
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Fri, 23 Dec 2016 23:39:36 +0100 |
parents | 692dddf298e2 |
children | d89d586b26ae |
files | kallithea/controllers/api/__init__.py |
diffstat | 1 files changed, 34 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/controllers/api/__init__.py Tue Jan 03 02:06:41 2017 +0100 +++ b/kallithea/controllers/api/__init__.py Fri Dec 23 23:39:36 2016 +0100 @@ -34,6 +34,7 @@ from paste.response import replace_header from pylons.controllers import WSGIController +from pylons.controllers.util import Response from pylons import request from webob.exc import HTTPError @@ -58,20 +59,16 @@ return safe_str(self.message) -def jsonrpc_error(message, retid=None, code=None): +class JSONRPCErrorResponse(Response, Exception): """ Generate a Response object with a JSON-RPC error body + """ - :param code: - :param retid: - :param message: - """ - from pylons.controllers.util import Response - return Response( - body=json.dumps(dict(id=retid, result=None, error=message)), - status=code, - content_type='application/json' - ) + def __init__(self, message=None, retid=None, code=None): + Response.__init__(self, + body=json.dumps(dict(id=retid, result=None, error=message)), + status=code, + content_type='application/json') class JSONRPCController(WSGIController): @@ -105,6 +102,8 @@ """ try: return self._handle_request(environ, start_response) + except JSONRPCErrorResponse as e: + return e finally: meta.Session.remove() @@ -114,16 +113,16 @@ self._req_id = None if 'CONTENT_LENGTH' not in environ: log.debug("No Content-Length") - return jsonrpc_error(retid=self._req_id, - message="No Content-Length in request") + raise JSONRPCErrorResponse(retid=self._req_id, + message="No Content-Length in request") else: length = environ['CONTENT_LENGTH'] or 0 length = int(environ['CONTENT_LENGTH']) log.debug('Content-Length: %s', length) if length == 0: - return jsonrpc_error(retid=self._req_id, - message="Content-Length is 0") + raise JSONRPCErrorResponse(retid=self._req_id, + message="Content-Length is 0") raw_body = environ['wsgi.input'].read(length) @@ -131,9 +130,9 @@ json_body = json.loads(raw_body) except ValueError as e: # catch JSON errors Here - return jsonrpc_error(retid=self._req_id, - message="JSON parse error ERR:%s RAW:%r" - % (e, raw_body)) + raise JSONRPCErrorResponse(retid=self._req_id, + message="JSON parse error ERR:%s RAW:%r" + % (e, raw_body)) # check AUTH based on API key try: @@ -144,38 +143,36 @@ if not isinstance(self._request_params, dict): self._request_params = {} - log.debug( - 'method: %s, params: %s', self._req_method, - self._request_params - ) + log.debug('method: %s, params: %s', + self._req_method, self._request_params) except KeyError as e: - return jsonrpc_error(retid=self._req_id, - message='Incorrect JSON query missing %s' % e) + raise JSONRPCErrorResponse(retid=self._req_id, + message='Incorrect JSON query missing %s' % e) # check if we can find this session using api_key try: u = User.get_by_api_key(self._req_api_key) if u is None: - return jsonrpc_error(retid=self._req_id, - message='Invalid API key') + raise JSONRPCErrorResponse(retid=self._req_id, + message='Invalid API key') auth_u = AuthUser(dbuser=u) if not AuthUser.check_ip_allowed(auth_u, ip_addr): - return jsonrpc_error(retid=self._req_id, - message='request from IP:%s not allowed' % (ip_addr,)) + raise JSONRPCErrorResponse(retid=self._req_id, + message='request from IP:%s not allowed' % (ip_addr,)) else: log.info('Access for IP:%s allowed', ip_addr) except Exception as e: - return jsonrpc_error(retid=self._req_id, - message='Invalid API key') + raise JSONRPCErrorResponse(retid=self._req_id, + message='Invalid API key') self._error = None try: self._func = self._find_method() except AttributeError as e: - return jsonrpc_error(retid=self._req_id, - message=str(e)) + raise JSONRPCErrorResponse(retid=self._req_id, + message=str(e)) # now that we have a method, add self._req_params to # self.kargs and dispatch control to WGIController @@ -207,19 +204,17 @@ # skip the required param check if it's default value is # NotImplementedType (default_empty) if default == default_empty and arg not in self._request_params: - return jsonrpc_error( + raise JSONRPCErrorResponse( retid=self._req_id, - message=( - 'Missing non optional `%s` arg in JSON DATA' % arg - ) + message='Missing non optional `%s` arg in JSON DATA' % arg, ) extra = set(self._request_params).difference(func_kwargs) if extra: - return jsonrpc_error( + raise JSONRPCErrorResponse( retid=self._req_id, - message=('Unknown %s arg in JSON DATA' % - ', '.join('`%s`' % arg for arg in extra)), + message='Unknown %s arg in JSON DATA' % + ', '.join('`%s`' % arg for arg in extra), ) self._rpc_args = {}