[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
|
return auth_method
|
||||||
|
|
||||||
def _handle_exception(self, exception):
|
def _handle_exception(self, exception):
|
||||||
# If handle exception return something different than None, it will be used as a response
|
# If handle_exception returns something different than None, it will be used as a response
|
||||||
raise
|
return request._handle_exception(exception)
|
||||||
|
|
||||||
def _dispatch(self):
|
def _dispatch(self):
|
||||||
# locate the controller method
|
# locate the controller method
|
||||||
|
|
|
@ -202,6 +202,13 @@ class WebRequest(object):
|
||||||
self.func_arguments = arguments
|
self.func_arguments = arguments
|
||||||
self.auth_method = auth
|
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):
|
def _call_function(self, *args, **kwargs):
|
||||||
request = self
|
request = self
|
||||||
if self.func_request_type != self._request_type:
|
if self.func_request_type != self._request_type:
|
||||||
|
@ -338,37 +345,15 @@ class JsonRequest(WebRequest):
|
||||||
self.params = dict(self.jsonrequest.get("params", {}))
|
self.params = dict(self.jsonrequest.get("params", {}))
|
||||||
self.context = self.params.pop('context', dict(self.session.context))
|
self.context = self.params.pop('context', dict(self.session.context))
|
||||||
|
|
||||||
def dispatch(self):
|
def _json_response(self, result=None, error=None):
|
||||||
""" Calls the method asked for by the JSON-RPC2 or JSONP request
|
response = {
|
||||||
"""
|
'jsonrpc': '2.0',
|
||||||
if self.jsonp_handler:
|
'id': self.jsonrequest.get('id')
|
||||||
return self.jsonp_handler()
|
}
|
||||||
response = {"jsonrpc": "2.0" }
|
if error is not None:
|
||||||
error = None
|
response['error'] = error
|
||||||
|
if result is not None:
|
||||||
try:
|
response['result'] = result
|
||||||
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
|
|
||||||
|
|
||||||
if self.jsonp:
|
if self.jsonp:
|
||||||
# If we use jsonp, that's mean we are called from another host
|
# If we use jsonp, that's mean we are called from another host
|
||||||
|
@ -381,8 +366,36 @@ class JsonRequest(WebRequest):
|
||||||
mime = 'application/json'
|
mime = 'application/json'
|
||||||
body = simplejson.dumps(response)
|
body = simplejson.dumps(response)
|
||||||
|
|
||||||
r = werkzeug.wrappers.Response(body, headers=[('Content-Type', mime), ('Content-Length', len(body))])
|
return werkzeug.wrappers.Response(
|
||||||
return r
|
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):
|
def serialize_exception(e):
|
||||||
tmp = {
|
tmp = {
|
||||||
|
|
Loading…
Reference in New Issue