From a29f189edc54a5d03d2df95b2467af29dd19fb5d Mon Sep 17 00:00:00 2001 From: Massimo DiPierro Date: Mon, 12 Mar 2012 15:30:29 -0500 Subject: [PATCH] better jsonrpc error handling, thanks Mariano --- VERSION | 2 +- gluon/contrib/simplejsonrpc.py | 20 +++++++++++--------- gluon/tools.py | 15 +++++++++++---- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/VERSION b/VERSION index d7932aa6..dfd560ae 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 1.99.7 (2012-03-12 15:27:08) dev +Version 1.99.7 (2012-03-12 15:30:27) dev diff --git a/gluon/contrib/simplejsonrpc.py b/gluon/contrib/simplejsonrpc.py index 4e9acdf0..6556b1f9 100644 --- a/gluon/contrib/simplejsonrpc.py +++ b/gluon/contrib/simplejsonrpc.py @@ -15,7 +15,7 @@ __author__ = "Mariano Reingart (reingart@gmail.com)" __copyright__ = "Copyright (C) 2011 Mariano Reingart" __license__ = "LGPL 3.0" -__version__ = "0.04" +__version__ = "0.05" import urllib @@ -34,13 +34,12 @@ except ImportError: class JSONRPCError(RuntimeError): "Error object for remote procedure call fail" - def __init__(self, code, message): + def __init__(self, code, message, data=None): + value = "%s: %s\n%s" % (code, message, '\n'.join(data)) + RuntimeError.__init__(self, value) self.code = code self.message = message - def __unicode__(self): - return u"%s: %s" % (self.code, self.message) - def __str__(self): - return self.__unicode__().encode("ascii","ignore") + self.data = data class JSONDummyParser: @@ -134,16 +133,19 @@ class ServerProxy(object): self.error = response.get('error', {}) if self.error and self.exceptions: - raise JSONRPCError(self.error.get('code', 0), self.error.get('message', '')) + raise JSONRPCError(self.error.get('code', 0), + self.error.get('message', ''), + self.error.get('data', None)) return response.get('result') +ServiceProxy = ServerProxy + + if __name__ == "__main__": # basic tests: location = "http://www.web2py.com.ar/webservices/sample/call/jsonrpc" client = ServerProxy(location, verbose='--verbose' in sys.argv,) print client.add(1, 2) - - diff --git a/gluon/tools.py b/gluon/tools.py index e284e68b..a8dd3c94 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -17,6 +17,7 @@ import glob import os import re import time +import traceback import smtplib import urllib import urllib2 @@ -3803,11 +3804,14 @@ class Service(object): def return_response(id, result): return serializers.json({'version': '1.1', 'id': id, 'result': result, 'error': None}) - def return_error(id, code, message): + def return_error(id, code, message, data=None): + error = {'name': 'JSONRPCError', + 'code': code, 'message': message} + if data is not None: + error['data'] = data return serializers.json({'id': id, 'version': '1.1', - 'error': {'name': 'JSONRPCError', - 'code': code, 'message': message} + 'error': error, }) request = current.request @@ -3827,7 +3831,10 @@ class Service(object): return return_error(id, e.code, e.info) except BaseException: etype, eval, etb = sys.exc_info() - return return_error(id, 100, '%s: %s' % (etype.__name__, eval)) + code = 100 + message = '%s: %s' % (etype.__name__, eval) + data = request.is_local and traceback.format_tb(etb) + return return_error(id, code, message, data) except: etype, eval, etb = sys.exc_info() return return_error(id, 100, 'Exception %s: %s' % (etype, eval))