diff --git a/addons/account/static/src/js/reconciliation/reconciliation_model.js b/addons/account/static/src/js/reconciliation/reconciliation_model.js index 2846e2d2e2f..bfea511f72e 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_model.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_model.js @@ -5,7 +5,7 @@ var BasicModel = require('web.BasicModel'); var field_utils = require('web.field_utils'); var utils = require('web.utils'); var session = require('web.session'); -var CrashManager = require('web.CrashManager'); +var WarningDialog = require('web.CrashManager').WarningDialog; var core = require('web.core'); var _t = core._t; @@ -636,7 +636,7 @@ var StatementModel = BasicModel.extend({ }); break; } - } + } else if (fieldName === 'tax_ids') { switch(value.operation) { case "ADD_M2M": diff --git a/addons/iap/static/src/js/crash_manager.js b/addons/iap/static/src/js/crash_manager.js index 59b07af1294..c1d01e2cd2a 100644 --- a/addons/iap/static/src/js/crash_manager.js +++ b/addons/iap/static/src/js/crash_manager.js @@ -3,7 +3,7 @@ odoo.define('iap.CrashManager', function (require) { var ajax = require('web.ajax'); var core = require('web.core'); -var CrashManager = require('web.CrashManager'); +var CrashManager = require('web.CrashManager').CrashManager; var Dialog = require('web.Dialog'); var _t = core._t; diff --git a/addons/point_of_sale/static/src/js/chrome.js b/addons/point_of_sale/static/src/js/chrome.js index 5e1ad64eb32..a63264a6e4d 100644 --- a/addons/point_of_sale/static/src/js/chrome.js +++ b/addons/point_of_sale/static/src/js/chrome.js @@ -8,7 +8,7 @@ var models = require('point_of_sale.models'); var AbstractAction = require('web.AbstractAction'); var core = require('web.core'); var ajax = require('web.ajax'); -var CrashManager = require('web.CrashManager'); +var CrashManager = require('web.CrashManager').CrashManager; var BarcodeEvents = require('barcodes.BarcodeEvents').BarcodeEvents; diff --git a/addons/web/static/src/js/chrome/abstract_web_client.js b/addons/web/static/src/js/chrome/abstract_web_client.js index 5adaaa36783..270f2871afe 100644 --- a/addons/web/static/src/js/chrome/abstract_web_client.js +++ b/addons/web/static/src/js/chrome/abstract_web_client.js @@ -15,9 +15,8 @@ var ActionManager = require('web.ActionManager'); var concurrency = require('web.concurrency'); var core = require('web.core'); var config = require('web.config'); -var crash_manager = require('web.crash_manager'); +var WarningDialog = require('web.CrashManager').WarningDialog; var data_manager = require('web.data_manager'); -var Dialog = require('web.Dialog'); var dom = require('web.dom'); var KeyboardNavigationMixin = require('web.KeyboardNavigationMixin'); var Loading = require('web.Loading'); @@ -29,7 +28,6 @@ var utils = require('web.utils'); var Widget = require('web.Widget'); var _t = core._t; -var qweb = core.qweb; var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMixin, { dependencies: ['notification'], @@ -393,11 +391,9 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, KeyboardNavigationMi _onDisplayWarning: function (e) { var data = e.data; if (data.type === 'dialog') { - new Dialog(this, { - size: 'medium', + new WarningDialog(this, { title: data.title, - $content: qweb.render("CrashManager.warning", data), - }).open({shouldFocusButtons: true}); + }, data).open(); } else { this.call('notification', 'notify', e.data); } diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js index af7628cc5ea..b17a3f501e6 100644 --- a/addons/web/static/src/js/core/ajax.js +++ b/addons/web/static/src/js/core/ajax.js @@ -27,11 +27,7 @@ function _genericJsonRpc (fct_name, params, settings, fct) { core.bus.trigger('rpc:result', data, result); if (result.error !== undefined) { if (result.error.data.arguments[0] !== "bus.Bus not available in test mode") { - var func = console.error; - if (result.error.data.exception_type === "user_error") { - func = console.log; - } - func( + console.debug( "Server application error\n", "Error code:", result.error.code, "\n", "Error message:", result.error.message, "\n", diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js index 7b3469e5e47..8681a869aba 100644 --- a/addons/web/static/src/js/services/crash_manager.js +++ b/addons/web/static/src/js/services/crash_manager.js @@ -4,21 +4,76 @@ odoo.define('web.CrashManager', function (require) { var ajax = require('web.ajax'); var core = require('web.core'); var Dialog = require('web.Dialog'); +var Widget = require('web.Widget'); -var QWeb = core.qweb; var _t = core._t; var _lt = core._lt; var map_title ={ - user_error: _lt('Warning'), - warning: _lt('Warning'), - access_error: _lt('Access Error'), - missing_error: _lt('Missing Record'), - validation_error: _lt('Validation Error'), - except_orm: _lt('Global Business Error'), - access_denied: _lt('Access Denied'), + user_error: _lt("User Error"), + warning: _lt("Warning"), + access_error: _lt("Access Error"), + missing_error: _lt("Missing Record"), + validation_error: _lt("Validation Error"), + except_orm: _lt("Global Business Error"), + access_denied: _lt("Access Denied"), }; +/** + * An extension of Dialog Widget to render the warnings and errors on the website. + * Extend it with your template of choice like ErrorDialog/WarningDialog + */ +var CrashManagerDialog = Dialog.extend({ + xmlDependencies: (Dialog.prototype.xmlDependencies || []).concat( + ['/web/static/src/xml/crash_manager.xml'] + ), + + /** + * @param {Object} error + * @param {string} error.message the message in Warning/Error Dialog + * @param {string} error.traceback the traceback in ErrorDialog + * + * @constructor + */ + init: function (parent, options, error) { + this._super.apply(this, [parent, options]); + this.message = error.message; + this.traceback = error.traceback; + }, +}); + +var ErrorDialog = CrashManagerDialog.extend({ + template: 'CrashManager.error', +}); + +var WarningDialog = CrashManagerDialog.extend({ + template: 'CrashManager.warning', + + /** + * Sets size to medium by default. + * + * @override + */ + init: function (parent, options, error) { + this._super(parent, _.extend({ + size: 'medium', + }, options), error); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Focuses the ok button. + * + * @override + */ + open: function () { + this._super({shouldFocusButtons: true}); + }, +}); + var CrashManager = core.Class.extend({ init: function () { var self = this; @@ -129,8 +184,8 @@ var CrashManager = core.Class.extend({ return; } if (_.has(map_title, error.data.exception_type)) { - if(error.data.exception_type === 'except_orm'){ - if(error.data.arguments[1]) { + if (error.data.exception_type === 'except_orm') { + if (error.data.arguments[1]) { error = _.extend({}, error, { data: _.extend({}, error.data, @@ -169,26 +224,30 @@ var CrashManager = core.Class.extend({ this.show_error(error); } }, - show_warning: function(error) { + show_warning: function (error) { if (!this.active) { return; } - return new Dialog(this, { - size: 'medium', - title: _.str.capitalize(error.type || error.message) || _t("Odoo Warning"), + var message = error.data ? error.data.message : error.message; + return new WarningDialog(this, { + title: _.str.capitalize(error.type) || _t("Odoo Warning"), subtitle: error.data.title, - $content: $(QWeb.render('CrashManager.warning', {error: error})) - }).open({shouldFocusButtons:true}); + }, { + message: message, + }).open(); }, - show_error: function(error) { + show_error: function (error) { if (!this.active) { return; } - var dialog = new Dialog(this, { - title: _.str.capitalize(error.type || error.message) || _t("Odoo Error"), - $content: $(QWeb.render('CrashManager.error', {error: error})) + var dialog = new ErrorDialog(this, { + title: _.str.capitalize(error.type) || _t("Odoo Error"), + }, { + message: error.message, + traceback: error.data.debug, }); + // When the dialog opens, initialize the copy feature and destroy it when the dialog is closed var $clipboardBtn; var clipboard; @@ -256,7 +315,7 @@ var ExceptionHandler = { * Handle redirection warnings, which behave more or less like a regular * warning, with an additional redirection button. */ -var RedirectWarningHandler = Dialog.extend(ExceptionHandler, { +var RedirectWarningHandler = Widget.extend(ExceptionHandler, { init: function(parent, error) { this._super(parent); this.error = error; @@ -264,10 +323,8 @@ var RedirectWarningHandler = Dialog.extend(ExceptionHandler, { display: function() { var self = this; var error = this.error; - error.data.message = error.data.arguments[0]; - new Dialog(this, { - size: 'medium', + new WarningDialog(this, { title: _.str.capitalize(error.type) || _t("Odoo Warning"), buttons: [ {text: error.data.arguments[2], classes : "btn-primary", click: function() { @@ -279,8 +336,9 @@ var RedirectWarningHandler = Dialog.extend(ExceptionHandler, { location.reload(); }}, {text: _t("Cancel"), click: function() { self.destroy(); }, close: true} - ], - $content: QWeb.render('CrashManager.warning', {error: error}), + ] + }, { + message: error.data.arguments[0], }).open(); } }); @@ -290,9 +348,9 @@ core.crash_registry.add('odoo.exceptions.RedirectWarning', RedirectWarningHandle function session_expired(cm) { return { display: function () { - cm.show_warning({type: _t("Odoo Session Expired"), data: {message: _t("Your Odoo session expired. Please refresh the current web page.")}}); + cm.show_warning({type: _t("Odoo Session Expired"), message: _t("Your Odoo session expired. Please refresh the current web page.")}); } - } + }; } core.crash_registry.add('odoo.http.SessionExpiredException', session_expired); core.crash_registry.add('werkzeug.exceptions.Forbidden', session_expired); @@ -302,18 +360,22 @@ core.crash_registry.add('504', function (cm) { display: function () { cm.show_warning({ type: _t("Request timeout"), - data: {message: _t("The operation was interrupted. This usually means that the current operation is taking too much time.")}}); + message: _t("The operation was interrupted. This usually means that the current operation is taking too much time.")}); } - } + }; }); -return CrashManager; +return { + CrashManager: CrashManager, + ErrorDialog: ErrorDialog, + WarningDialog: WarningDialog, +}; }); odoo.define('web.crash_manager', function (require) { "use strict"; -var CrashManager = require('web.CrashManager'); +var CrashManager = require('web.CrashManager').CrashManager; return new CrashManager(); }); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 950f24c792c..d214e2e692e 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -120,30 +120,6 @@ -
An error occurred
-Please use the copy button to report the error to your support service.
--
-