[IMP] Better exception handling

bzr revid: fme@openerp.com-20131205150633-lnfvhjq42n0r26tv
This commit is contained in:
Fabien Meghazi 2013-12-05 16:06:33 +01:00
parent 1049e1c859
commit 2a2f50e08f
3 changed files with 112 additions and 91 deletions

View File

@ -96,7 +96,7 @@ class Website(openerp.addons.web.controllers.main.Home):
if request.context['editable']:
page = 'website.page_404'
else:
return request.registry['ir.http']._handle_404(e)
return request.registry['ir.http']._handle_exception(e, 404)
return request.website.render(page, values)
@website.route('/website/customize_template_toggle', type='json', auth='user')

View File

@ -61,7 +61,7 @@ class ir_http(orm.AbstractModel):
request.lang = request.context['lang'] = path.pop(1)
path = '/'.join(path) or '/'
return self.reroute(path)
return self._handle_404()
return self._handle_exception(code=404)
return super(ir_http, self)._dispatch()
def reroute(self, path):
@ -79,37 +79,44 @@ class ir_http(orm.AbstractModel):
return self._dispatch()
def _handle_403(self, exception):
def _handle_exception(self, exception=None, code=500):
if isinstance(exception, werkzeug.exceptions.HTTPException) and exception.response:
return exception.response
if getattr(request, 'cms', False) and request.website:
logger.warn("403 Forbidden:\n\n%s", traceback.format_exc(exception))
self._auth_method_public()
return self._render_error(403, {
'error': exception.message
})
raise exception
values = dict(
exception=exception,
traceback=traceback.format_exc(exception),
)
if exception:
if isinstance(exception, openerp.exceptions.AccessError):
code = 403
else:
code = getattr(exception, 'code', code)
values.update(
qweb_template=getattr(exception, 'qweb_template', None),
qweb_node=getattr(exception, 'qweb_node', None),
qweb_eval=getattr(exception, 'qweb_eval', None),
)
if code == 500:
logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
elif code == 403:
logger.warn("403 Forbidden:\n\n%s", values['traceback'])
def _handle_404(self, exception=None):
if getattr(request, 'cms', False) and request.website:
return self._render_error(404)
raise request.not_found()
values.update(
status_message=werkzeug.http.HTTP_STATUS_CODES[code],
status_code=code,
)
def _handle_500(self, exception):
if getattr(request, 'cms', False) and request.website:
logger.error("500 Internal Server Error:\n\n%s", traceback.format_exc(exception))
return self._render_error(500, {
'exception': exception,
'traceback': traceback.format_exc(),
'qweb_template': getattr(exception, 'qweb_template', None),
'qweb_node': getattr(exception, 'qweb_node', None),
'qweb_eval': getattr(exception, 'qweb_eval', None),
})
raise exception
if not request.uid:
self._auth_method_public()
def _render_error(self, code, values=None):
return werkzeug.wrappers.Response(
request.website._render('website.%s' % code, values),
status=code,
content_type='text/html;charset=utf-8')
try:
html = request.website._render('website.%s' % code, values)
except:
html = request.website._render('website.http_error', values)
return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
return super(ir_http, self)._handle_exception(exception)
class ModelConverter(ir.ir_http.ModelConverter):
def __init__(self, url_map, model=False):

View File

@ -385,6 +385,74 @@
</t>
</template>
<template id="http_error">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure">
<h1 class="container mt32"><t t-esc="status_code"/>: <t t-esc="status_message"/></h1>
</div>
<t t-if="editable or request.debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
</t>
</template>
<template id="http_error_debug">
<div class="container panel-group mb32 mt32" id="debug_infos">
<div class="panel panel-default" t-if="exception">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#debug_infos" href="#error_main">
Error
</a>
</h4>
</div>
<div id="error_main" class="panel-collapse collapse in">
<div class="panel-body">
<p t-if="website_controller">The following error was raised in the website controller <code t-esc="website_controller"/></p>
<p><strong>Error message:</strong> <pre t-esc="exception.message"/></p>
</div>
</div>
</div>
<div class="panel panel-default" t-if="qweb_template">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#adebug_infos" href="#error_qweb">
QWeb
</a>
</h4>
</div>
<div id="error_qweb" class="panel-collapse collapse">
<div class="panel-body">
<p>
The error occured while rendering the template <code t-esc="qweb_template"/>
<t t-if="qweb_eval">and evaluating the following expression: <code t-esc="qweb_eval"/></t>
</p>
<t t-if="qweb_node">
<pre id="exception_node" t-esc="qweb_node.toxml()"/>
</t>
</div>
</div>
</div>
<div class="panel panel-default" t-if="traceback">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#adebug_infos" href="#error_traceback">
Traceback
</a>
</h4>
</div>
<div id="error_traceback" class="panel-collapse collapse">
<div class="panel-body">
<pre id="exception_traceback" t-esc="traceback"/>
</div>
</div>
</div>
</div>
</template>
<template id="404">
<t t-call="website.layout">
<div id="wrap">
@ -404,70 +472,16 @@
</ul>
</div>
</div>
<t t-if="request.debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
</t>
</template>
<template id="500">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure">
<h1 class="container mt32">500: Internal Server Error!</h1>
</div>
<div class="container panel-group" id="debug_infos" t-if="editable">
<div class="panel panel-default" t-if="exception">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#debug_infos" href="#error_main">
Error
</a>
</h4>
</div>
<div id="error_main" class="panel-collapse collapse in">
<div class="panel-body">
<p t-if="website_controller">The following error was raised in the website controller <code t-esc="website_controller"/></p>
<p><strong>Error message:</strong> <t t-esc="exception.message"/></p>
</div>
</div>
</div>
<div class="panel panel-default" t-if="qweb_template">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#adebug_infos" href="#error_qweb">
QWeb
</a>
</h4>
</div>
<div id="error_qweb" class="panel-collapse collapse">
<div class="panel-body">
<p>
The error occured while rendering the template <code t-esc="qweb_template"/>
<t t-if="qweb_eval">and evaluating the following expression: <code t-esc="qweb_eval"/></t>
</p>
<t t-if="qweb_node">
<pre id="exception_node" t-esc="qweb_node.toxml()"/>
</t>
</div>
</div>
</div>
<div class="panel panel-default" t-if="traceback">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#adebug_infos" href="#error_traceback">
Traceback
</a>
</h4>
</div>
<div id="error_traceback" class="panel-collapse collapse">
<div class="panel-body">
<pre id="exception_traceback" t-esc="traceback"/>
</div>
</div>
</div>
</div>
</div>
</t>
<t t-call="website.http_error"/>
</template>
<template id="403">
@ -479,9 +493,6 @@
The page you were looking for could not be
authorized.
</p>
<t t-if="error and editable">
<pre t-esc="error"/>
</t>
<p>
Maybe you were looking for one of these
popular pages ?
@ -491,6 +502,9 @@
<li><a href="/page/website.contactus/">Contact Us</a></li>
</ul>
</div>
<t t-if="editable or request.debug">
<t t-call="website.http_error_debug"/>
</t>
</div>
</t>
</template>