[FIX] request.handle_exception: cleanup override logic, fixed chain broken by commit a096ae0
handle_exception() is supposed to try handling an exception and if it cannot, re-raise it. Overridden methods must therefore call super() within a try/except block, and only attempt to handle the exception if super() raised.
This commit is contained in:
parent
7a3b7f7fe2
commit
51c7b55da0
|
@ -99,45 +99,45 @@ class ir_http(orm.AbstractModel):
|
||||||
werkzeug.exceptions.abort(werkzeug.utils.redirect(url))
|
werkzeug.exceptions.abort(werkzeug.utils.redirect(url))
|
||||||
|
|
||||||
def _handle_exception(self, exception=None, code=500):
|
def _handle_exception(self, exception=None, code=500):
|
||||||
res = super(ir_http, self)._handle_exception(exception)
|
try:
|
||||||
if isinstance(exception, werkzeug.exceptions.HTTPException) and hasattr(exception, 'response') and exception.response:
|
return super(ir_http, self)._handle_exception(exception)
|
||||||
return exception.response
|
except Exception:
|
||||||
if getattr(request, 'website_enabled', False) and request.website:
|
if getattr(request, 'website_enabled', False) and request.website:
|
||||||
values = dict(
|
values = dict(
|
||||||
exception=exception,
|
exception=exception,
|
||||||
traceback=traceback.format_exc(exception),
|
traceback=traceback.format_exc(exception),
|
||||||
)
|
)
|
||||||
if exception:
|
if exception:
|
||||||
code = getattr(exception, 'code', code)
|
code = getattr(exception, 'code', code)
|
||||||
if isinstance(exception, ir_qweb.QWebException):
|
if isinstance(exception, ir_qweb.QWebException):
|
||||||
values.update(qweb_exception=exception)
|
values.update(qweb_exception=exception)
|
||||||
if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
|
if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
|
||||||
code = 403
|
code = 403
|
||||||
if code == 500:
|
if code == 500:
|
||||||
logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
|
logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
|
||||||
if 'qweb_exception' in values:
|
if 'qweb_exception' in values:
|
||||||
view = request.registry.get("ir.ui.view")
|
view = request.registry.get("ir.ui.view")
|
||||||
views = view._views_get(request.cr, request.uid, exception.qweb['template'], request.context)
|
views = view._views_get(request.cr, request.uid, exception.qweb['template'], request.context)
|
||||||
to_reset = [v for v in views if v.model_data_id.noupdate is True]
|
to_reset = [v for v in views if v.model_data_id.noupdate is True]
|
||||||
values['views'] = to_reset
|
values['views'] = to_reset
|
||||||
elif code == 403:
|
elif code == 403:
|
||||||
logger.warn("403 Forbidden:\n\n%s", values['traceback'])
|
logger.warn("403 Forbidden:\n\n%s", values['traceback'])
|
||||||
|
|
||||||
values.update(
|
values.update(
|
||||||
status_message=werkzeug.http.HTTP_STATUS_CODES[code],
|
status_message=werkzeug.http.HTTP_STATUS_CODES[code],
|
||||||
status_code=code,
|
status_code=code,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not request.uid:
|
if not request.uid:
|
||||||
self._auth_method_public()
|
self._auth_method_public()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
html = request.website._render('website.%s' % code, values)
|
html = request.website._render('website.%s' % code, values)
|
||||||
except Exception:
|
except Exception:
|
||||||
html = request.website._render('website.http_error', values)
|
html = request.website._render('website.http_error', values)
|
||||||
return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
|
return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
|
||||||
|
|
||||||
return res
|
raise
|
||||||
|
|
||||||
class ModelConverter(ir.ir_http.ModelConverter):
|
class ModelConverter(ir.ir_http.ModelConverter):
|
||||||
def __init__(self, url_map, model=False):
|
def __init__(self, url_map, model=False):
|
||||||
|
|
|
@ -208,6 +208,9 @@ class WebRequest(object):
|
||||||
to abitrary responses. Anything returned (except None) will
|
to abitrary responses. Anything returned (except None) will
|
||||||
be used as response."""
|
be used as response."""
|
||||||
self._failed = exception # prevent tx commit
|
self._failed = exception # prevent tx commit
|
||||||
|
if isinstance(exception, werkzeug.exceptions.HTTPException):
|
||||||
|
return exception
|
||||||
|
raise
|
||||||
|
|
||||||
def _call_function(self, *args, **kwargs):
|
def _call_function(self, *args, **kwargs):
|
||||||
request = self
|
request = self
|
||||||
|
@ -373,18 +376,20 @@ class JsonRequest(WebRequest):
|
||||||
def _handle_exception(self, exception):
|
def _handle_exception(self, exception):
|
||||||
"""Called within an except block to allow converting exceptions
|
"""Called within an except block to allow converting exceptions
|
||||||
to abitrary responses. Anything returned (except None) will
|
to abitrary responses. Anything returned (except None) will
|
||||||
be used as response."""
|
be used as response."""
|
||||||
super(JsonRequest, self)._handle_exception(exception)
|
try:
|
||||||
_logger.exception("Exception during JSON request handling.")
|
return super(JsonRequest, self)._handle_exception(exception)
|
||||||
error = {
|
except Exception:
|
||||||
'code': 200,
|
_logger.exception("Exception during JSON request handling.")
|
||||||
'message': "OpenERP Server Error",
|
error = {
|
||||||
'data': serialize_exception(exception)
|
'code': 200,
|
||||||
}
|
'message': "OpenERP Server Error",
|
||||||
if isinstance(exception, AuthenticationError):
|
'data': serialize_exception(exception)
|
||||||
error['code'] = 100
|
}
|
||||||
error['message'] = "OpenERP Session Invalid"
|
if isinstance(exception, AuthenticationError):
|
||||||
return self._json_response(error=error)
|
error['code'] = 100
|
||||||
|
error['message'] = "OpenERP Session Invalid"
|
||||||
|
return self._json_response(error=error)
|
||||||
|
|
||||||
def dispatch(self):
|
def dispatch(self):
|
||||||
""" Calls the method asked for by the JSON-RPC2 or JSONP request
|
""" Calls the method asked for by the JSON-RPC2 or JSONP request
|
||||||
|
|
Loading…
Reference in New Issue