[FIX] http,ir.http: refactor exception handling to allow request-specific handling
Typically an exception during a JSON-RPC request must be handled specifically and return a JSON-RPC error in all cases. Previously the _authenticate() step could fail during ir_http.dispatch() and bubble up to werkzeug, yielding a dumb "Internal Server Error 500" even for a JSON-RPC request. bzr revid: odo@openerp.com-20140328142748-00haplmkc3fv6f9y
This commit is contained in:
parent
9379dc0312
commit
8809c77f60
|
@ -85,8 +85,8 @@ class ir_http(osv.AbstractModel):
|
|||
return auth_method
|
||||
|
||||
def _handle_exception(self, exception):
|
||||
# If handle exception return something different than None, it will be used as a response
|
||||
raise
|
||||
# If handle_exception returns something different than None, it will be used as a response
|
||||
return request._handle_exception(exception)
|
||||
|
||||
def _dispatch(self):
|
||||
# locate the controller method
|
||||
|
|
|
@ -202,6 +202,13 @@ class WebRequest(object):
|
|||
self.func_arguments = arguments
|
||||
self.auth_method = auth
|
||||
|
||||
|
||||
def _handle_exception(self, exception):
|
||||
"""Called within an except block to allow converting exceptions
|
||||
to abitrary responses. Anything returned (except None) will
|
||||
be used as response."""
|
||||
raise
|
||||
|
||||
def _call_function(self, *args, **kwargs):
|
||||
request = self
|
||||
if self.func_request_type != self._request_type:
|
||||
|
@ -338,37 +345,15 @@ class JsonRequest(WebRequest):
|
|||
self.params = dict(self.jsonrequest.get("params", {}))
|
||||
self.context = self.params.pop('context', dict(self.session.context))
|
||||
|
||||
def dispatch(self):
|
||||
""" Calls the method asked for by the JSON-RPC2 or JSONP request
|
||||
"""
|
||||
if self.jsonp_handler:
|
||||
return self.jsonp_handler()
|
||||
response = {"jsonrpc": "2.0" }
|
||||
error = None
|
||||
|
||||
try:
|
||||
response['id'] = self.jsonrequest.get('id')
|
||||
response["result"] = self._call_function(**self.params)
|
||||
except AuthenticationError, e:
|
||||
_logger.exception("Exception during JSON request handling.")
|
||||
se = serialize_exception(e)
|
||||
error = {
|
||||
'code': 100,
|
||||
'message': "OpenERP Session Invalid",
|
||||
'data': se
|
||||
}
|
||||
self._failed = e # prevent tx commit
|
||||
except Exception, e:
|
||||
_logger.exception("Exception during JSON request handling.")
|
||||
se = serialize_exception(e)
|
||||
error = {
|
||||
'code': 200,
|
||||
'message': "OpenERP Server Error",
|
||||
'data': se
|
||||
}
|
||||
self._failed = e # prevent tx commit
|
||||
if error:
|
||||
response["error"] = error
|
||||
def _json_response(self, result=None, error=None):
|
||||
response = {
|
||||
'jsonrpc': '2.0',
|
||||
'id': self.jsonrequest.get('id')
|
||||
}
|
||||
if error is not None:
|
||||
response['error'] = error
|
||||
if result is not None:
|
||||
response['result'] = result
|
||||
|
||||
if self.jsonp:
|
||||
# If we use jsonp, that's mean we are called from another host
|
||||
|
@ -381,8 +366,36 @@ class JsonRequest(WebRequest):
|
|||
mime = 'application/json'
|
||||
body = simplejson.dumps(response)
|
||||
|
||||
r = werkzeug.wrappers.Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
|
||||
return r
|
||||
return werkzeug.wrappers.Response(
|
||||
body, headers=[('Content-Type', mime),
|
||||
('Content-Length', len(body))])
|
||||
|
||||
def _handle_exception(self, exception):
|
||||
"""Called within an except block to allow converting exceptions
|
||||
to abitrary responses. Anything returned (except None) will
|
||||
be used as response."""
|
||||
_logger.exception("Exception during JSON request handling.")
|
||||
self._failed = exception # prevent tx commit
|
||||
error = {
|
||||
'code': 200,
|
||||
'message': "OpenERP Server Error",
|
||||
'data': serialize_exception(exception)
|
||||
}
|
||||
if isinstance(exception, AuthenticationError):
|
||||
error['code'] = 100
|
||||
error['message'] = "OpenERP Session Invalid"
|
||||
return self._json_response(error=error)
|
||||
|
||||
def dispatch(self):
|
||||
""" Calls the method asked for by the JSON-RPC2 or JSONP request
|
||||
"""
|
||||
if self.jsonp_handler:
|
||||
return self.jsonp_handler()
|
||||
try:
|
||||
result = self._call_function(**self.params)
|
||||
return self._json_response(result)
|
||||
except Exception, e:
|
||||
return self._handle_exception(e)
|
||||
|
||||
def serialize_exception(e):
|
||||
tmp = {
|
||||
|
|
Loading…
Reference in New Issue