[FIX] web, *: make crash_manager use services correctly
* = website_forum, stock Fix for: https://github.com/odoo/odoo/pull/32132 crash_manager.js was using the services while bypassing ServiceProviderMixin That means all services are duplicated, each having their own state. To fix this issue, CrashManager now extends AbstractService. Also crash_manager is now registered in serviceRegistry instead of being instanciated on the fly. The crash_manager now being a Service raise one issue with the tests: The services are not run for the tests but some tests needs the crash_manager 'unhandledrejection' listener. For that matter the services are reenable in qunit. Also the crash_manager's 'unhandledrejection' listener has to have precedence over the qunit listener as it will handle rejections wich have no reason or are not Errors. Part of: https://github.com/odoo/odoo/pull/35209
This commit is contained in:
@@ -6,7 +6,6 @@ var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var ReportWidget = require('stock.ReportWidget');
|
||||
var framework = require('web.framework');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
|
||||
@@ -104,7 +103,7 @@ var stock_report_generic = AbstractAction.extend({
|
||||
url: url_data.replace('output_format', 'pdf'),
|
||||
data: {data: JSON.stringify(dict)},
|
||||
complete: framework.unblockUI,
|
||||
error: crash_manager.rpc_error.bind(crash_manager),
|
||||
error: () => this.call('crash_manager', 'rpc_error', ...arguments),
|
||||
});
|
||||
});
|
||||
return this.$buttons;
|
||||
|
||||
@@ -8,7 +8,6 @@ odoo.define('web.ReportActionManager', function (require) {
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var framework = require('web.framework');
|
||||
var session = require('web.session');
|
||||
|
||||
@@ -54,8 +53,8 @@ ActionManager.include({
|
||||
data: JSON.stringify([url, type]),
|
||||
},
|
||||
success: resolve,
|
||||
error: function () {
|
||||
crash_manager.rpc_error.apply(crash_manager, arguments);
|
||||
error: () => {
|
||||
this.call('crash_manager', 'rpc_error', ...arguments);
|
||||
reject();
|
||||
},
|
||||
complete: framework.unblockUI,
|
||||
|
||||
@@ -2,9 +2,9 @@ odoo.define('web.framework', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var ajax = require('web.ajax');
|
||||
var Widget = require('web.Widget');
|
||||
var disableCrashManager = require('web.CrashManager').disable;
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
@@ -101,7 +101,7 @@ function unblockUI() {
|
||||
*/
|
||||
function redirect (url, wait) {
|
||||
// Dont display a dialog if some xmlhttprequest are in progress
|
||||
crash_manager.disable();
|
||||
disableCrashManager();
|
||||
|
||||
var load = function() {
|
||||
var old = "" + window.location;
|
||||
|
||||
@@ -10,7 +10,6 @@ odoo.define('web.basic_fields', function (require) {
|
||||
var AbstractField = require('web.AbstractField');
|
||||
var config = require('web.config');
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var datepicker = require('web.datepicker');
|
||||
var dom = require('web.dom');
|
||||
var Domain = require('web.Domain');
|
||||
@@ -1928,11 +1927,10 @@ var FieldBinaryFile = AbstractFieldBinary.extend({
|
||||
ev.stopPropagation();
|
||||
} else if (this.res_id) {
|
||||
framework.blockUI();
|
||||
var c = crash_manager;
|
||||
var filename_fieldname = this.attrs.filename;
|
||||
this.getSession().get_file({
|
||||
'url': '/web/content',
|
||||
'data': {
|
||||
complete: framework.unblockUI,
|
||||
data: {
|
||||
'model': this.model,
|
||||
'id': this.res_id,
|
||||
'field': this.name,
|
||||
@@ -1941,8 +1939,8 @@ var FieldBinaryFile = AbstractFieldBinary.extend({
|
||||
'download': true,
|
||||
'data': utils.is_bin_size(this.value) ? null : this.value,
|
||||
},
|
||||
'complete': framework.unblockUI,
|
||||
'error': c.rpc_error.bind(c),
|
||||
error: () => this.call('crash_manager', 'rpc_error', ...arguments),
|
||||
url: '/web/content',
|
||||
});
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
odoo.define('web.CrashManager', function (require) {
|
||||
"use strict";
|
||||
|
||||
const AbstractService = require('web.AbstractService');
|
||||
var ajax = require('web.ajax');
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var mixins = require('web.mixins');
|
||||
var ServicesMixin = require('web.ServicesMixin');
|
||||
var ServiceProviderMixin = require('web.ServiceProviderMixin');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var _t = core._t;
|
||||
@@ -23,6 +21,14 @@ var map_title ={
|
||||
karma_error: _lt("Karma Error"),
|
||||
};
|
||||
|
||||
// Register this eventlistener before qunit does.
|
||||
// Some errors needs to be negated by the crash_manager.
|
||||
window.addEventListener('unhandledrejection', ev =>
|
||||
core.bus.trigger('crash_manager_unhandledrejection', ev)
|
||||
);
|
||||
|
||||
let active = true;
|
||||
|
||||
/**
|
||||
* An extension of Dialog Widget to render the warnings and errors on the website.
|
||||
* Extend it with your template of choice like ErrorDialog/WarningDialog
|
||||
@@ -78,13 +84,13 @@ var WarningDialog = CrashManagerDialog.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, ServiceProviderMixin,{
|
||||
var CrashManager = AbstractService.extend({
|
||||
init: function () {
|
||||
var self = this;
|
||||
this.active = true;
|
||||
active = true;
|
||||
this.isConnected = true;
|
||||
|
||||
mixins.EventDispatcherMixin.init.call(this);
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// crash manager integration
|
||||
core.bus.on('rpc_error', this, this.rpc_error);
|
||||
@@ -128,7 +134,7 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin,
|
||||
|
||||
// listen to unhandled rejected promises, and throw an error when the
|
||||
// promise has been rejected due to a crash
|
||||
window.addEventListener('unhandledrejection', function (ev) {
|
||||
core.bus.on('crash_manager_unhandledrejection', this, function (ev) {
|
||||
if (ev.reason && ev.reason instanceof Error) {
|
||||
var traceback = ev.reason.stack;
|
||||
self.show_error({
|
||||
@@ -144,13 +150,12 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin,
|
||||
ev.preventDefault();
|
||||
}
|
||||
});
|
||||
ServiceProviderMixin.init.call(this);
|
||||
},
|
||||
enable: function () {
|
||||
this.active = true;
|
||||
active = true;
|
||||
},
|
||||
disable: function () {
|
||||
this.active = false;
|
||||
active = false;
|
||||
},
|
||||
handleLostConnection: function () {
|
||||
var self = this;
|
||||
@@ -175,7 +180,12 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin,
|
||||
}, delay);
|
||||
},
|
||||
rpc_error: function(error) {
|
||||
if (!this.active) {
|
||||
// Some qunit tests produces errors before the DOM is set.
|
||||
// This produces an error loop as the modal/toast has no DOM to attach to.
|
||||
if (!document.body) {
|
||||
return;
|
||||
}
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
if (this.connection_lost) {
|
||||
@@ -229,7 +239,7 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin,
|
||||
}
|
||||
},
|
||||
show_warning: function (error, options) {
|
||||
if (!this.active) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
var message = error.data ? error.data.message : error.message;
|
||||
@@ -243,7 +253,7 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin,
|
||||
}, options));
|
||||
},
|
||||
show_error: function (error) {
|
||||
if (!this.active) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
var dialog = new ErrorDialog(this, {
|
||||
@@ -371,17 +381,12 @@ core.crash_registry.add('504', function (cm) {
|
||||
};
|
||||
});
|
||||
|
||||
core.serviceRegistry.add('crash_manager', CrashManager);
|
||||
|
||||
return {
|
||||
CrashManager: CrashManager,
|
||||
ErrorDialog: ErrorDialog,
|
||||
WarningDialog: WarningDialog,
|
||||
disable: () => active = false,
|
||||
};
|
||||
});
|
||||
|
||||
odoo.define('web.crash_manager', function (require) {
|
||||
"use strict";
|
||||
|
||||
var CrashManager = require('web.CrashManager').CrashManager;
|
||||
return new CrashManager();
|
||||
|
||||
});
|
||||
|
||||
@@ -14,7 +14,6 @@ odoo.define('web.PivotController', function (require) {
|
||||
|
||||
var AbstractController = require('web.AbstractController');
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var framework = require('web.framework');
|
||||
var session = require('web.session');
|
||||
|
||||
@@ -126,7 +125,7 @@ var PivotController = AbstractController.extend({
|
||||
_downloadTable: function () {
|
||||
var table = this.model.exportData();
|
||||
if(table.measure_row.length + 1 > 256) {
|
||||
crash_manager.show_message(_t("For Excel compatibility, data cannot be exported if there are more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures."));
|
||||
this.call('crash_manager', 'show_message', _t("For Excel compatibility, data cannot be exported if there are more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures."));
|
||||
framework.unblockUI();
|
||||
return;
|
||||
}
|
||||
@@ -136,7 +135,7 @@ var PivotController = AbstractController.extend({
|
||||
url: '/web/pivot/export_xls',
|
||||
data: {data: JSON.stringify(table)},
|
||||
complete: framework.unblockUI,
|
||||
error: crash_manager.rpc_error.bind(crash_manager)
|
||||
error: () => this.call('crash_manager', 'rpc_error', ...arguments),
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@ odoo.define('web.DataExport', function (require) {
|
||||
|
||||
var config = require('web.config');
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var Dialog = require('web.Dialog');
|
||||
var data = require('web.data');
|
||||
var framework = require('web.framework');
|
||||
@@ -168,7 +167,7 @@ var DataExport = Dialog.extend({
|
||||
})
|
||||
},
|
||||
complete: framework.unblockUI,
|
||||
error: crash_manager.rpc_error.bind(crash_manager),
|
||||
error: () => this.call('crash_manager', 'rpc_error', ...arguments),
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -572,27 +572,9 @@
|
||||
<script type="text/javascript" src="/web/static/lib/ace/mode-js.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
odoo.define('web.WebClientWithoutServices', function (require) {
|
||||
var ServiceProviderMixin = require('web.ServiceProviderMixin');
|
||||
var WebClient = require('web.WebClient');
|
||||
var WebClientWithoutServices = WebClient.extend({
|
||||
/**
|
||||
* Patch web client so that it is no longer a service provider.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
var originalServiceProviderMixinInit = ServiceProviderMixin.init;
|
||||
ServiceProviderMixin.init = function () {};
|
||||
this._super.apply(this, arguments);
|
||||
ServiceProviderMixin.init = originalServiceProviderMixinInit;
|
||||
},
|
||||
});
|
||||
return WebClientWithoutServices;
|
||||
});
|
||||
// define the 'web.web_client' module because some other modules require it
|
||||
odoo.define('web.web_client', function (require) {
|
||||
var WebClient = require('web.WebClientWithoutServices');
|
||||
var WebClient = require('web.WebClient');
|
||||
var web_client = new WebClient();
|
||||
return web_client;
|
||||
});
|
||||
|
||||
@@ -2,7 +2,6 @@ odoo.define('website_forum.website_forum', function (require) {
|
||||
'use strict';
|
||||
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var Wysiwyg = require('web_editor.wysiwyg.root');
|
||||
var publicWidget = require('web.public.widget');
|
||||
var session = require('web.session');
|
||||
@@ -190,7 +189,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
msg = _t("Sorry you must be logged in to perform this action");
|
||||
title = _t("Access Denied");
|
||||
}
|
||||
crash_manager.show_warning({
|
||||
this.call('crash_manager', 'show_warning', {
|
||||
message: msg,
|
||||
title: title,
|
||||
}, {
|
||||
@@ -237,6 +236,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onFlagAlertClick: function (ev) {
|
||||
var self = this;
|
||||
ev.preventDefault();
|
||||
var $link = $(ev.currentTarget);
|
||||
this._rpc({
|
||||
@@ -251,7 +251,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
} else if (data.error === 'post_non_flaggable') {
|
||||
message = _t("This post can not be flagged");
|
||||
}
|
||||
crash_manager.show_warning({
|
||||
self.call('crash_manager', 'show_warning', {
|
||||
message: message,
|
||||
title: _t("Access Denied"),
|
||||
}, {
|
||||
@@ -278,6 +278,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onVotePostClick: function (ev) {
|
||||
var self = this;
|
||||
ev.preventDefault();
|
||||
var $link = $(ev.currentTarget);
|
||||
this._rpc({
|
||||
@@ -290,7 +291,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
} else if (data.error === 'anonymous_user') {
|
||||
message = _t('Sorry you must be logged to vote');
|
||||
}
|
||||
crash_manager.show_warning({
|
||||
self.call('crash_manager', 'show_warning', {
|
||||
message: message,
|
||||
title: _t("Access Denied"),
|
||||
}, {
|
||||
@@ -334,6 +335,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onAcceptAnswerClick: function (ev) {
|
||||
var self = this;
|
||||
ev.preventDefault();
|
||||
var $link = $(ev.currentTarget);
|
||||
this._rpc({
|
||||
@@ -343,7 +345,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
if (data.error === 'anonymous_user') {
|
||||
var message = _t("Sorry, anonymous users cannot choose correct answer.");
|
||||
}
|
||||
crash_manager.show_warning({
|
||||
self.call('crash_manager', 'show_warning', {
|
||||
message: message,
|
||||
title: _t("Access Denied"),
|
||||
}, {
|
||||
|
||||
Reference in New Issue
Block a user