summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/gamification/models/gamification_karma_rank.py21
-rw-r--r--addons/stock/controllers/main.py3
-rw-r--r--addons/test_website/__manifest__.py1
-rw-r--r--addons/test_website/controllers/main.py9
-rw-r--r--addons/test_website/static/tests/tours/error_views.js25
-rw-r--r--addons/web/controllers/main.py7
-rw-r--r--addons/web/static/src/js/services/crash_manager.js1
-rw-r--r--odoo/addons/base/models/ir_http.py30
-rw-r--r--odoo/http.py37
9 files changed, 90 insertions, 44 deletions
diff --git a/addons/gamification/models/gamification_karma_rank.py b/addons/gamification/models/gamification_karma_rank.py
index 78b8e40ac50..cd4ef6cc28a 100644
--- a/addons/gamification/models/gamification_karma_rank.py
+++ b/addons/gamification/models/gamification_karma_rank.py
@@ -1,15 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from werkzeug.exceptions import Forbidden
-
-from odoo import api, tools, fields, models
+from odoo import api, tools, fields, models, exceptions, http
from odoo.tools.translate import html_translate
-class KarmaError(Forbidden):
+class KarmaError(exceptions.except_orm):
""" Karma-related error, used for forum and posts. """
- pass
+ def __init__(self, msg):
+ super(KarmaError, self).__init__(msg)
+
+
+class Http(models.AbstractModel):
+ _inherit = 'ir.http'
+
+ @classmethod
+ def serialize_exception(self, e):
+ res = super(Http, self).serialize_exception(e)
+ if isinstance(e, KarmaError):
+ res["exception_type"] = "karma_error"
+ return res
class KarmaRank(models.Model):
diff --git a/addons/stock/controllers/main.py b/addons/stock/controllers/main.py
index e18b0e6da96..05d6f5b0ead 100644
--- a/addons/stock/controllers/main.py
+++ b/addons/stock/controllers/main.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
-from odoo.addons.web.controllers.main import _serialize_exception
from odoo.tools import html_escape
import json
@@ -37,7 +36,7 @@ class StockReportController(http.Controller):
response.set_cookie('fileToken', token)
return response
except Exception as e:
- se = _serialize_exception(e)
+ se = request.env['ir.http'].serialize_exception(e)
error = {
'code': 200,
'message': 'Odoo Server Error',
diff --git a/addons/test_website/__manifest__.py b/addons/test_website/__manifest__.py
index 557722971d4..e1bac638412 100644
--- a/addons/test_website/__manifest__.py
+++ b/addons/test_website/__manifest__.py
@@ -14,6 +14,7 @@ dependencies. Neither we want to add in website module some routes, views and
models which only purpose is to run tests.""",
'depends': [
'website',
+ 'gamification',
],
'data': [
'views/templates.xml',
diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py
index cc60ccfd25f..0a8210881c7 100644
--- a/addons/test_website/controllers/main.py
+++ b/addons/test_website/controllers/main.py
@@ -8,6 +8,7 @@ from odoo import http
from odoo.http import request
from odoo.addons.portal.controllers.web import Home
from odoo.exceptions import UserError, ValidationError, AccessError, MissingError, AccessError, AccessDenied
+from odoo.addons.gamification.models.gamification_karma_rank import KarmaError
class WebsiteTest(Home):
@@ -80,6 +81,14 @@ class WebsiteTest(Home):
def test_missing_error_http(self, **kwargs):
raise MissingError("This is a missing http test")
+ @http.route('/test_karma_error_json', type='json', auth='public', website=True)
+ def test_karma_error_rpc(self, **kwargs):
+ raise KarmaError("This is a karma rpc test")
+
+ @http.route('/test_karma_error_http', type='http', auth='public', website=True)
+ def test_karma_error_http(self, **kwargs):
+ raise KarmaError("This is a karma http test")
+
@http.route('/test_internal_error_json', type='json', auth='public', website=True)
def test_internal_error_json(self, **kwargs):
raise werkzeug.exceptions.InternalServerError()
diff --git a/addons/test_website/static/tests/tours/error_views.js b/addons/test_website/static/tests/tours/error_views.js
index a3d9f3fa035..f76ba28ff8e 100644
--- a/addons/test_website/static/tests/tours/error_views.js
+++ b/addons/test_website/static/tests/tours/error_views.js
@@ -45,6 +45,13 @@ tour.register('test_error_website', {
extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is an access denied rpc test")',
trigger: 'button.btn.btn-primary',
}, {
+ content: "trigger rpc missing error",
+ trigger: 'a[href="/test_karma_error_json"]',
+ }, {
+ content: "rpc missing error modal has message",
+ extra_trigger: 'div.o_dialog_warning.modal-body:contains("This is a karma rpc test")',
+ trigger: 'button.btn.btn-primary',
+ }, {
content: "trigger rpc error 500",
trigger: 'a[href="/test_internal_error_json"]',
}, {
@@ -132,6 +139,24 @@ tour.register('test_error_website', {
window.location.href = window.location.origin + '/test_karma_error_http?debug=0';
},
}, {
+ content: "http karma error page has title and message",
+ extra_trigger: 'h1:contains("Oops! Something went wrong.")',
+ trigger: 'div.container pre:contains("This is a karma http test")',
+ run: function () {
+ window.location.href = window.location.origin + '/test_karma_error_http?debug=1';
+ },
+ }, {
+ content: "http karma error page debug has title and message open",
+ extra_trigger: 'h1:contains("Oops! Something went wrong.")',
+ trigger: 'div#error_main.collapse.show pre:contains("This is a karma http test")',
+ run: function () {},
+ }, {
+ content: "http karma error page debug has traceback closed",
+ trigger: 'body:has(div#error_traceback.collapse:not(.show) pre#exception_traceback)',
+ run: function () {
+ window.location.href = window.location.origin + '/test_access_denied_http?debug=0';
+ },
+ }, {
content: "http error 403 page has title but no message",
extra_trigger: 'h1:contains("403: Forbidden")',
trigger: 'div#wrap:not(:has(pre:contains("This is an access denied http test"))', //See ir_http.py handle_exception, the exception is replaced so there is no message !
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index 860cf454dd4..7aca92712a8 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -42,8 +42,7 @@ from odoo.tools.translate import _
from odoo.tools.misc import str2bool, xlwt, file_open
from odoo.tools.safe_eval import safe_eval
from odoo import http, tools
-from odoo.http import content_disposition, dispatch_rpc, request, \
- serialize_exception as _serialize_exception, Response
+from odoo.http import content_disposition, dispatch_rpc, request, Response
from odoo.exceptions import AccessError, UserError, AccessDenied
from odoo.models import check_method_name
from odoo.service import db, security
@@ -83,7 +82,7 @@ def serialize_exception(f):
return f(*args, **kwargs)
except Exception as e:
_logger.exception("An exception occured during an http request")
- se = _serialize_exception(e)
+ se = request.registry['ir.http'].serialize_exception(e)
error = {
'code': 200,
'message': "Odoo Server Error",
@@ -1694,7 +1693,7 @@ class ReportController(http.Controller):
else:
return
except Exception as e:
- se = _serialize_exception(e)
+ se = request.env['ir.http'].serialize_exception(e)
error = {
'code': 200,
'message': "Odoo Server Error",
diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js
index 8681a869aba..a8fafa4b897 100644
--- a/addons/web/static/src/js/services/crash_manager.js
+++ b/addons/web/static/src/js/services/crash_manager.js
@@ -17,6 +17,7 @@ var map_title ={
validation_error: _lt("Validation Error"),
except_orm: _lt("Global Business Error"),
access_denied: _lt("Access Denied"),
+ karma_error: _lt("Karma Error"),
};
/**
diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py
index 897ca1de9ba..3f49b4052fc 100644
--- a/odoo/addons/base/models/ir_http.py
+++ b/odoo/addons/base/models/ir_http.py
@@ -9,6 +9,7 @@ import mimetypes
import os
import re
import sys
+import traceback
import werkzeug
import werkzeug.exceptions
@@ -20,7 +21,7 @@ import odoo
from odoo import api, http, models, tools, SUPERUSER_ID
from odoo.exceptions import AccessDenied, AccessError
from odoo.http import request, STATIC_CACHE, content_disposition
-from odoo.tools import pycompat, consteq
+from odoo.tools import consteq, pycompat, ustr
from odoo.tools.mimetypes import guess_mimetype
from odoo.modules.module import get_resource_path, get_module_path
@@ -179,6 +180,33 @@ class IrHttp(models.AbstractModel):
return False
@classmethod
+ def serialize_exception(self, e):
+ tmp = {
+ "name": type(e).__module__ + "." + type(e).__name__ if type(e).__module__ else type(e).__name__,
+ "debug": traceback.format_exc(),
+ "message": ustr(e),
+ "arguments": e.args,
+ "exception_type": "internal_error"
+ }
+ if isinstance(e, odoo.exceptions.UserError):
+ tmp["exception_type"] = "user_error"
+ elif isinstance(e, odoo.exceptions.Warning):
+ tmp["exception_type"] = "warning"
+ elif isinstance(e, odoo.exceptions.RedirectWarning):
+ tmp["exception_type"] = "warning"
+ elif isinstance(e, odoo.exceptions.AccessError):
+ tmp["exception_type"] = "access_error"
+ elif isinstance(e, odoo.exceptions.MissingError):
+ tmp["exception_type"] = "missing_error"
+ elif isinstance(e, odoo.exceptions.AccessDenied):
+ tmp["exception_type"] = "access_denied"
+ elif isinstance(e, odoo.exceptions.ValidationError):
+ tmp["exception_type"] = "validation_error"
+ elif isinstance(e, odoo.exceptions.except_orm):
+ tmp["exception_type"] = "except_orm"
+ return tmp
+
+ @classmethod
def _handle_exception(cls, exception):
# in case of Exception, e.g. 404, we don't step into _dispatch
cls._handle_debug()
diff --git a/odoo/http.py b/odoo/http.py
index ab4512a6321..25200ebcecf 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -98,16 +98,16 @@ def replace_request_password(args):
args[2] = '*'
return tuple(args)
+
# don't trigger debugger for those exceptions, they carry user-facing warnings
# and indications, they're not necessarily indicative of anything being
# *broken*
-NO_POSTMORTEM = (odoo.osv.orm.except_orm,
- odoo.exceptions.AccessError,
- odoo.exceptions.ValidationError,
- odoo.exceptions.MissingError,
+NO_POSTMORTEM = (odoo.exceptions.except_orm,
odoo.exceptions.AccessDenied,
odoo.exceptions.Warning,
odoo.exceptions.RedirectWarning)
+
+
def dispatch_rpc(service_name, method, params):
""" Handle a RPC call.
@@ -316,7 +316,7 @@ class WebRequest(object):
"""Called within an except block to allow converting exceptions
to abitrary responses. Anything returned (except None) will
be used as response."""
- self._failed = exception # prevent tx commit
+ self._failed = exception # prevent tx commit
if not isinstance(exception, NO_POSTMORTEM) \
and not isinstance(exception, werkzeug.exceptions.HTTPException):
odoo.tools.debugger.post_mortem(
@@ -641,7 +641,7 @@ class JsonRequest(WebRequest):
error = {
'code': 200,
'message': "Odoo Server Error",
- 'data': serialize_exception(exception),
+ 'data': request.registry['ir.http'].serialize_exception(exception),
}
if isinstance(exception, werkzeug.exceptions.NotFound):
error['http_status'] = 404
@@ -691,31 +691,6 @@ class JsonRequest(WebRequest):
except Exception as e:
return self._handle_exception(e)
-def serialize_exception(e):
- tmp = {
- "name": type(e).__module__ + "." + type(e).__name__ if type(e).__module__ else type(e).__name__,
- "debug": traceback.format_exc(),
- "message": ustr(e),
- "arguments": e.args,
- "exception_type": "internal_error"
- }
- if isinstance(e, odoo.exceptions.UserError):
- tmp["exception_type"] = "user_error"
- elif isinstance(e, odoo.exceptions.Warning):
- tmp["exception_type"] = "warning"
- elif isinstance(e, odoo.exceptions.RedirectWarning):
- tmp["exception_type"] = "warning"
- elif isinstance(e, odoo.exceptions.AccessError):
- tmp["exception_type"] = "access_error"
- elif isinstance(e, odoo.exceptions.MissingError):
- tmp["exception_type"] = "missing_error"
- elif isinstance(e, odoo.exceptions.AccessDenied):
- tmp["exception_type"] = "access_denied"
- elif isinstance(e, odoo.exceptions.ValidationError):
- tmp["exception_type"] = "validation_error"
- elif isinstance(e, odoo.exceptions.except_orm):
- tmp["exception_type"] = "except_orm"
- return tmp
class HttpRequest(WebRequest):
""" Handler for the ``http`` request type.