Changed exception handling in jsonrpc

bzr revid: nicolas.vanhoren@openerp.com-20130130143049-hofmnixydlf42dds
This commit is contained in:
niv-openerp 2013-01-30 15:30:49 +01:00
parent e2618f83ff
commit 79f7eaf08c
3 changed files with 53 additions and 75 deletions

View File

@ -14,7 +14,6 @@ import re
import simplejson
import time
import urllib2
import xmlrpclib
import zlib
from xml.etree import ElementTree
from cStringIO import StringIO
@ -97,7 +96,7 @@ def db_monodb(req):
dbs = db_list(req)
if len(dbs) == 1:
return dbs[0]
except xmlrpclib.Fault:
except Exception:
# ignore access denied
pass
return False
@ -749,10 +748,10 @@ class Database(openerpweb.Controller):
try:
return req.session.proxy("db").drop(password, db)
except xmlrpclib.Fault, e:
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
return {'error': e.faultCode, 'title': 'Drop Database'}
return {'error': _('Could not drop database !'), 'title': _('Drop Database')}
except openerp.exceptions.AccessDenied:
return {'error': 'AccessDenied', 'title': 'Drop Database'}
except Exception:
return {'error': _('Could not drop database !'), 'title': _('Drop Database')}
@openerpweb.httprequest
def backup(self, req, backup_db, backup_pwd, token):
@ -769,8 +768,8 @@ class Database(openerpweb.Controller):
('Content-Disposition', content_disposition(filename, req))],
{'fileToken': int(token)}
)
except xmlrpclib.Fault, e:
return simplejson.dumps([[],[{'error': e.faultCode, 'title': _('Backup Database')}]])
except Exception, e:
return simplejson.dumps([[],[{'error': openerp.tools.ustr(e), 'title': _('Backup Database')}]])
@openerpweb.httprequest
def restore(self, req, db_file, restore_pwd, new_db):
@ -778,9 +777,8 @@ class Database(openerpweb.Controller):
data = base64.b64encode(db_file.read())
req.session.proxy("db").restore(restore_pwd, new_db, data)
return ''
except xmlrpclib.Fault, e:
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
raise Exception("AccessDenied")
except openerp.exceptions.AccessDenied, e:
raise Exception("AccessDenied")
@openerpweb.jsonrequest
def change_password(self, req, fields):
@ -789,10 +787,10 @@ class Database(openerpweb.Controller):
dict(map(operator.itemgetter('name', 'value'), fields)))
try:
return req.session.proxy("db").change_admin_password(old_password, new_password)
except xmlrpclib.Fault, e:
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
return {'error': e.faultCode, 'title': _('Change Password')}
return {'error': _('Error, password not changed !'), 'title': _('Change Password')}
except openerp.exceptions.AccessDenied:
return {'error': 'AccessDenied', 'title': _('Change Password')}
except Exception:
return {'error': _('Error, password not changed !'), 'title': _('Change Password')}
class Session(openerpweb.Controller):
_cp_path = "/web/session"
@ -1194,7 +1192,7 @@ class Binary(openerpweb.Controller):
image_data = base64.b64decode(image_base64)
except (TypeError, xmlrpclib.Fault):
except Exception:
image_data = self.placeholder(req)
headers.append(('ETag', retag))
headers.append(('Content-Length', len(image_data)))
@ -1311,7 +1309,7 @@ class Binary(openerpweb.Controller):
'filename': ufile.filename,
'id': attachment_id
}
except xmlrpclib.Fault, e:
except Exception:
args = {'error':e.faultCode }
return out % (simplejson.dumps(callback), simplejson.dumps(args))

View File

@ -19,7 +19,6 @@ import time
import traceback
import urlparse
import uuid
import xmlrpclib
import babel.core
import simplejson
@ -194,35 +193,23 @@ class JsonRequest(WebRequest):
response['id'] = self.jsonrequest.get('id')
response["result"] = method(self, **self.params)
except session.AuthenticationError:
se = serialize_exception(e)
error = {
'code': 100,
'message': "OpenERP Session Invalid",
'data': {
'data': dict(se, **{
'type': 'session_invalid',
'debug': traceback.format_exc()
}
})
}
except xmlrpclib.Fault, e:
except Exception, e:
se = serialize_exception(e)
error = {
'code': 200,
'message': "OpenERP Server Error",
'data': {
'data': dict(se, **{
'type': 'server_exception',
'fault_code': e.faultCode,
'debug': "Client %s\nServer %s" % (
"".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString)
}
}
except Exception:
logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\
("An error occured while handling a json request")
error = {
'code': 300,
'message': "OpenERP WebClient Error",
'data': {
'type': 'client_exception',
'debug': "Client %s" % traceback.format_exc()
}
'fault_code': se["message"],
})
}
if error:
response["error"] = error
@ -244,6 +231,27 @@ class JsonRequest(WebRequest):
r = werkzeug.wrappers.Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
return r
def serialize_exception(e):
return {
"name": type(e).__module__ + "." + type(e).__name__ if type(e).__module__ else type(e).__name__,
"debug": traceback.format_exc(),
"message": u"%s" % e,
"arguments": to_jsonable(e.args),
}
def to_jsonable(o):
if isinstance(o, str) or isinstance(o,unicode) or isinstance(o, int) or isinstance(o, long) \
or isinstance(o, bool) or o is None or isinstance(o, float):
return o
if isinstance(o, list) or isinstance(o, tuple):
return [to_jsonable(x) for x in o]
if isinstance(o, dict):
tmp = {}
for k, v in o.items():
tmp[u"%s" % k] = to_jsonable(v)
return tmp
return u"%s" % o
def jsonrequest(f):
""" Decorator marking the decorated method as being a handler for a
JSON-RPC request (the exact request path is specified via the
@ -274,28 +282,17 @@ class HttpRequest(WebRequest):
_logger.debug("%s --> %s.%s %r", self.httprequest.method, method.im_class.__name__, method.__name__, akw)
try:
r = method(self, **self.params)
except xmlrpclib.Fault, e:
r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps({
except Exception:
se = serialize_exception(e)
error = {
'code': 200,
'message': "OpenERP Server Error",
'data': {
'data': dict(se, **{
'type': 'server_exception',
'fault_code': e.faultCode,
'debug': "Server %s\nClient %s" % (
e.faultString, traceback.format_exc())
}
})))
except Exception:
logging.getLogger(__name__ + '.HttpRequest.dispatch').exception(
"An error occurred while handling a json request")
r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps({
'code': 300,
'message': "OpenERP WebClient Error",
'data': {
'type': 'client_exception',
'debug': "Client %s" % traceback.format_exc()
}
})))
'fault_code': se["message"],
})
}
r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps(error)))
if self.debug or 1:
if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
_logger.debug('<-- %s', r)

View File

@ -6,7 +6,6 @@ import logging
import time
import traceback
import sys
import xmlrpclib
import openerp
@ -85,23 +84,7 @@ class OpenERPSession(object):
self.jsonp_requests = {} # FIXME use a LRU
def send(self, service_name, method, *args):
code_string = u"warning -- %s\n\n%s"
try:
return openerp.netsvc.dispatch_rpc(service_name, method, args)
except openerp.osv.osv.except_osv, e:
raise xmlrpclib.Fault(code_string % (e.name, e.value), '')
except openerp.exceptions.Warning, e:
raise xmlrpclib.Fault(code_string % ("Warning", e), '')
except openerp.exceptions.AccessError, e:
raise xmlrpclib.Fault(code_string % ("AccessError", e), '')
except openerp.exceptions.AccessDenied, e:
raise xmlrpclib.Fault('AccessDenied', openerp.tools.ustr(e))
except openerp.exceptions.DeferredException, e:
formatted_info = "".join(traceback.format_exception(*e.traceback))
raise xmlrpclib.Fault(openerp.tools.ustr(e), formatted_info)
except Exception, e:
formatted_info = "".join(traceback.format_exception(*(sys.exc_info())))
raise xmlrpclib.Fault(openerp.tools.ustr(e), formatted_info)
return openerp.netsvc.dispatch_rpc(service_name, method, args)
def proxy(self, service):
return Service(self, service)