diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 44b3f771f62..8be35f5a9ae 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -74,7 +74,6 @@ class ir_http(orm.AbstractModel): # to url without language so google doesn't see duplicate content return request.redirect(path + '?' + request.httprequest.query_string) return self.reroute(path) - return self._handle_exception(code=404) return super(ir_http, self)._dispatch() def reroute(self, path): @@ -103,8 +102,8 @@ class ir_http(orm.AbstractModel): try: _, path = rule.build(arguments) assert path is not None - except Exception: - return self._handle_exception(werkzeug.exceptions.NotFound()) + except Exception, e: + return self._handle_exception(e, code=404) if request.httprequest.method in ('GET', 'HEAD'): generated_path = werkzeug.url_unquote_plus(path) @@ -136,55 +135,70 @@ class ir_http(orm.AbstractModel): if response.status_code == 304: return response - response.mimetype = attach[0]['mimetype'] + response.mimetype = attach[0]['mimetype'] or 'application/octet-stream' response.data = datas.decode('base64') return response - def _handle_exception(self, exception=None, code=500): - try: + def _handle_exception(self, exception, code=500): + # This is done first as the attachment path may + # not match any HTTP controller, so the request + # may not be website-enabled. + attach = self._serve_attachment() + if attach: + return attach + + is_website_request = bool(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) - except Exception: + else: + try: + response = super(ir_http, self)._handle_exception(exception) + if isinstance(response, Exception): + exception = response + else: + # if parent excplicitely returns a plain response, then we don't touch it + return response + except Exception, e: + exception = e - attach = self._serve_attachment() - if attach: - return attach + values = dict( + exception=exception, + traceback=traceback.format_exc(exception), + ) + code = getattr(exception, 'code', code) - if getattr(request, 'website_enabled', False) and request.website: - values = dict( - exception=exception, - traceback=traceback.format_exc(exception), - ) - if exception: - code = getattr(exception, 'code', code) - if isinstance(exception, ir_qweb.QWebException): - values.update(qweb_exception=exception) - 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']) + if isinstance(exception, openerp.exceptions.AccessError): + code = 403 - values.update( - status_message=werkzeug.http.HTTP_STATUS_CODES[code], - status_code=code, - ) + if isinstance(exception, ir_qweb.QWebException): + values.update(qweb_exception=exception) + if isinstance(exception.qweb.get('cause'), openerp.exceptions.AccessError): + code = 403 - if not request.uid: - self._auth_method_public() + 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']) - 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') + values.update( + status_message=werkzeug.http.HTTP_STATUS_CODES[code], + status_code=code, + ) - raise + 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): def __init__(self, url_map, model=False, domain='[]'): diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index f20a0b1d5ef..89c4a33ed54 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -208,12 +208,16 @@ class WebsiteForum(http.Controller): }, context=context) return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), new_question_id)) - @http.route(['''/forum//question//question/