[IMP] http errors refactoring

bzr revid: fme@openerp.com-20131125165958-0k84rp9rbsxvav77
This commit is contained in:
Fabien Meghazi 2013-11-25 17:59:58 +01:00
parent 0b6fb91448
commit cc424c1a55
4 changed files with 142 additions and 92 deletions

View File

@ -91,7 +91,13 @@ class Website(openerp.addons.web.controllers.main.Home):
values = {
'path': page,
}
try:
request.website.get_template(page)
except (Exception), e:
if request.context['editable']:
page = 'website.page_404'
else:
return request.registry['ir.http']._handle_404(e)
return request.website.render(page, values)
@website.route('/website/customize_template_toggle', type='json', auth='user')

View File

@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
import traceback
import werkzeug.routing
import openerp
from openerp.osv import orm
from openerp.http import request
from openerp.addons.base import ir
from openerp.http import request
from openerp.osv import orm
from ..utils import slugify
from website import get_current_website
class ir_http(orm.AbstractModel):
_inherit = 'ir.http'
@ -24,6 +26,33 @@ class ir_http(orm.AbstractModel):
else:
request.uid = request.session.uid
def _handle_403(self, exception):
return self._render_error(403, {
'error': exception.message
})
def _handle_404(self, exception):
return self._render_error(404)
def _handle_500(self, exception):
# TODO: proper logging
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),
})
def _render_error(self, code, values=None):
self._auth_method_public()
if not hasattr(request, 'website'):
request.website = get_current_website()
request.website.preprocess_request(request)
return werkzeug.wrappers.Response(
request.website._render('website.%s' % code, values),
status=code,
content_type='text/html;charset=utf-8')
class ModelConverter(ir.ir_http.ModelConverter):
def __init__(self, url_map, model=False):

View File

@ -6,7 +6,6 @@ import logging
import psycopg2
import math
import itertools
import traceback
import urllib
import urlparse
@ -16,7 +15,6 @@ import werkzeug.exceptions
import werkzeug.wrappers
import openerp
from openerp.exceptions import AccessError, AccessDenied
from openerp.osv import orm, osv, fields
from openerp.tools.safe_eval import safe_eval
@ -41,29 +39,22 @@ def route(routes, *route_args, **route_kwargs):
request.route_lang = kwargs.pop('lang_code', None)
if not hasattr(request, 'website'):
request.multilang = f.multilang
# TODO: Select website, currently hard coded
request.website = request.registry['website'].browse(
request.cr, request.uid, 1, context=request.context)
request.website = get_current_website()
if request.route_lang:
lang_ok = [lg.code for lg in request.website.language_ids if lg.code == request.route_lang]
if not lang_ok:
return request.not_found()
request.website.preprocess_request(request)
try:
return f(*args, **kwargs)
except Exception, err:
logger.exception("Website Rendering Error.")
if request.context['is_public_user']:
return request.website.render("website.401")
else:
return request.website.render("website.500", {
'traceback': traceback.format_exc(),
'controller': [f.__module__, "%s.%s" % (args[0].__class__.__name__, f.__name__)],
})
return f(*args, **kwargs)
return wrap
return decorator
def get_current_website():
# TODO: Select website, currently hard coded
return request.registry['website'].browse(request.cr, request.uid, 1, context=request.context)
def url_for(path_or_uri, lang=None, keep_query=None):
location = path_or_uri.strip()
url = urlparse.urlparse(location)
@ -159,6 +150,9 @@ class website(osv.osv):
def redirect(url):
return werkzeug.utils.redirect(url_for(url))
request.redirect = redirect
if not hasattr(request, 'multilang'):
# TODO: try to get rid of this multilang attribute
request.multilang = False
is_public_user = request.uid == self.get_public_user(cr, uid, context).id
@ -186,9 +180,17 @@ class website(osv.osv):
'translatable': not is_public_user and not is_master_lang and request.multilang,
})
def _render(self, cr, uid, ids, template, values=None, context=None):
view = self.pool.get("ir.ui.view")
def get_template(self, cr, uid, ids, template, context=None):
IMD = self.pool.get("ir.model.data")
try:
module, xmlid = template.split('.', 1)
view_ref = IMD.get_object_reference(cr, uid, module, xmlid)
except ValueError: # catches both unpack errors and gor errors
module, xmlid = 'website', template
view_ref = IMD.get_object_reference(cr, uid, module, xmlid)
return self.pool.get("ir.ui.view").browse(cr, uid, view_ref[1])
def _render(self, cr, uid, ids, template, values=None, context=None):
user = self.pool.get("res.users")
if not context:
@ -212,43 +214,12 @@ class website(osv.osv):
inherit_branding=qweb_context.setdefault('editable', False),
)
view_ref = None
# check if xmlid of the template exists
try:
module, xmlid = template.split('.', 1)
view_ref = IMD.get_object_reference(cr, uid, module, xmlid)
except ValueError: # catches both unpack errors and gor errors
module, xmlid = 'website', template
try:
view_ref = IMD.get_object_reference(cr, uid, module, xmlid)
except ValueError:
return self.error(cr, uid, 404, qweb_context, context=context)
view = self.get_template(cr, uid, ids, template)
if 'main_object' not in qweb_context:
try:
main_object = self.pool[view_ref[0]].browse(cr, uid, view_ref[1])
qweb_context['main_object'] = main_object
except Exception:
pass
qweb_context['main_object'] = view
try:
return view.render(
cr, uid, "%s.%s" % (module, xmlid), qweb_context,
engine='website.qweb', context=context)
except (AccessError, AccessDenied), err:
logger.error(err)
qweb_context['error'] = err[1]
logger.warn("Website Rendering Error.\n\n%s" % traceback.format_exc())
return self.error(cr, uid, 401, qweb_context, context=context)
except Exception, e:
qweb_context['template'] = getattr(e, 'qweb_template', '')
node = getattr(e, 'qweb_node', None)
qweb_context['node'] = node and node.toxml()
qweb_context['expr'] = getattr(e, 'qweb_eval', '')
qweb_context['traceback'] = traceback.format_exc()
logger.exception("Website Rendering Error.\n%(template)s\n%(expr)s\n%(node)s" % qweb_context)
return self.error(cr, uid, 500 if qweb_context['editable'] else 404,
qweb_context, context=context)
return view.render(qweb_context, engine='website.qweb', context=context)
def render(self, cr, uid, ids, template, values=None, context=None):
def callback(template, values, context):
@ -257,13 +228,6 @@ class website(osv.osv):
values = {}
return LazyResponse(callback, template=template, values=values, context=context)
def error(self, cr, uid, code, qweb_context, context=None):
View = request.registry['ir.ui.view']
return werkzeug.wrappers.Response(
View.render(cr, uid, 'website.%d' % code, qweb_context),
status=code,
content_type='text/html;charset=utf-8')
def pager(self, cr, uid, ids, url, total, page=1, step=30, scope=5, url_args=None, context=None):
# Compute Pager
page_count = int(math.ceil(float(total) / step))

View File

@ -29,7 +29,7 @@
</template>
<template id="layout" name="Main layout">&lt;!DOCTYPE html&gt;
<html t-att-lang="lang.replace('_', '-')"
<html t-att-lang="lang and lang.replace('_', '-')"
t-att-data-website-id="website.id if editable else None"
t-att-data-editable="'1' if editable else None"
t-att-data-translatable="'1' if translatable else None"
@ -365,34 +365,40 @@
</t>
</template>
<template id="404">
<t t-call="website.layout">
<div id="wrap">
<div class="container" t-if="editable and path">
<template id="page_404">
<t t-call="website.404">
<div class="container">
<div class="well mt32">
<p>This page does not exists, but you can create it as you are administrator of this site.</p>
<a class="btn btn-primary" t-att-href="'/pagenew/'+path">Create Page</a>
<a class="btn btn-primary" t-attf-href="/pagenew/#{ path }">Create Page</a>
<span class="text-muted">or</span> <a href="/sitemap">Search a Page</a>
</div>
<div class="text-center text-muted">Edit the content bellow this line to adapt the default "page not found" page.</div>
</div>
<hr />
<div class="oe_structure oe_empty">
<div class="container">
<h1 class="mt32">404: Page not found!</h1>
<p>
The page you were looking for could not be found; it is possible you have
typed the address incorrectly, but it has most probably been removed due
to the recent website reorganisation.
</p>
<p>Maybe you were looking for one of these popular pages ?</p>
<ul>
<li><a href="/">Homepage</a></li>
<li><a href="/page/website.contactus/">Contact Us</a></li>
</ul>
<hr/>
</t>
</template>
<template id="404">
<t t-call="website.layout">
<div id="wrap">
<t t-raw="0"/>
<div class="oe_structure oe_empty">
<div class="container">
<h1 class="mt32">404: Page not found!</h1>
<p>
The page you were looking for could not be found; it is possible you have
typed the address incorrectly, but it has most probably been removed due
to the recent website reorganisation.
</p>
<p>Maybe you were looking for one of these popular pages ?</p>
<ul>
<li><a href="/">Homepage</a></li>
<li><a href="/page/website.contactus/">Contact Us</a></li>
</ul>
</div>
</div>
</div>
</div>
</t>
</template>
@ -402,22 +408,67 @@
<div class="oe_structure">
<h1 class="container mt32">500: Internal Server Error!</h1>
</div>
<t t-if="editable">
<h3 t-if="template">Exception in template: <span id="exception_template" t-esc="template"/></h3>
<h3 t-if="controller">Exception in controller: <span id="exception_controller" t-esc="controller[1]"/> <small>(Module: <span id="exception_module" t-esc="controller[0]"/>)</small> </h3>
<h4 t-if="expr">Expression: <t t-esc="expr"/></h4>
<t t-if="node"><pre id="exception_node" t-esc="node"/></t>
<pre id="exception_traceback" t-esc="traceback"/>
</t>
<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>
</template>
<template id="401">
<template id="403">
<t t-call="website.layout">
<div id="wrap">
<div class="container">
<h1 class="mt32">401: Unauthorized Access!</h1>
<h1 class="mt32">403: Forbidden</h1>
<p>
The page you were looking for could not be
authorized.