[FIX] _handle_exception() logic amongst requests and ir_http objects

Changes in website's ir_http#_handle_exception():

- exception is mandatory, can't be None anymore
- we don't touch non website_enabled requests
- we don't touch explicits plain responses from parent
- logic flow is now easier to read (I hope so)

Change in website's ir_http#_dispatch():

- In case of real 404, instead of returning self._handle_exception(),
  just let parent do the job (so we call super())
This commit is contained in:
Fabien Meghazi 2014-06-25 11:47:44 +02:00
parent e1e0cfbba8
commit 4e0799e163
1 changed files with 47 additions and 38 deletions

View File

@ -60,7 +60,6 @@ class ir_http(orm.AbstractModel):
request.lang = request.context['lang'] = path.pop(1) request.lang = request.context['lang'] = path.pop(1)
path = '/'.join(path) or '/' path = '/'.join(path) or '/'
return self.reroute(path) return self.reroute(path)
return self._handle_exception(code=404)
return super(ir_http, self)._dispatch() return super(ir_http, self)._dispatch()
def reroute(self, path): def reroute(self, path):
@ -93,51 +92,61 @@ class ir_http(orm.AbstractModel):
if str(arg.id) != placeholder.value and placeholder.value != good_slug: if str(arg.id) != placeholder.value and placeholder.value != good_slug:
# TODO: properly recompose the url instead of using replace() # TODO: properly recompose the url instead of using replace()
url = url.replace(placeholder.value, good_slug) url = url.replace(placeholder.value, good_slug)
except KeyError: except KeyError, e:
return self._handle_exception(werkzeug.exceptions.NotFound()) return self._handle_exception(e, code=404)
if url != original_url: if url != original_url:
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, code=500):
try: is_website_request = getattr(request, 'website_enabled', False) and request.website
if not is_website_request:
# Don't touch non website requests exception handling
return super(ir_http, self)._handle_exception(exception) return super(ir_http, self)._handle_exception(exception)
except Exception: else:
if getattr(request, 'website_enabled', False) and request.website: try:
values = dict( response = super(ir_http, self)._handle_exception(exception)
exception=exception, if isinstance(response, Exception):
traceback=traceback.format_exc(exception), exception = response
) else:
if exception: # if parent excplicitely returns a plain response, then we don't touch it
code = getattr(exception, 'code', code) return response
if isinstance(exception, ir_qweb.QWebException): except Exception, e:
values.update(qweb_exception=exception) exception = e
if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
code = 403
if code == 500:
logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
if 'qweb_exception' in values:
view = request.registry.get("ir.ui.view")
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]
values['views'] = to_reset
elif code == 403:
logger.warn("403 Forbidden:\n\n%s", values['traceback'])
values.update( values = dict(
status_message=werkzeug.http.HTTP_STATUS_CODES[code], exception=exception,
status_code=code, traceback=traceback.format_exc(exception),
) )
code = getattr(exception, 'code', code)
if not request.uid: if isinstance(exception, ir_qweb.QWebException):
self._auth_method_public() values.update(qweb_exception=exception)
if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError):
code = 403
try: if code == 500:
html = request.website._render('website.%s' % code, values) logger.error("500 Internal Server Error:\n\n%s", values['traceback'])
except Exception: if 'qweb_exception' in values:
html = request.website._render('website.http_error', values) view = request.registry.get("ir.ui.view")
return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8') 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]
values['views'] = to_reset
elif code == 403:
logger.warn("403 Forbidden:\n\n%s", values['traceback'])
raise values.update(
status_message=werkzeug.http.HTTP_STATUS_CODES[code],
status_code=code,
)
if not request.uid:
self._auth_method_public()
try:
html = request.website._render('website.%s' % code, values)
except Exception:
html = request.website._render('website.http_error', values)
return werkzeug.wrappers.Response(html, status=code, content_type='text/html;charset=utf-8')
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):