[FIX] web: do_action open twice error dialog
Before this commit, using a do_action that throws an error opened two error dialogs. To solve this, in the compatibility layer, we check that the error has not already been thrown. To reproduce the problem, you can execute an action using do_action which will return an error. For example, an action performing an rpc and the server returns an error. You can find an example scenario to test the problem on the 2618694. closes odoo/odoo#77148 X-original-commit: 582604990e28c329348475f373b03295903ed77e Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -230,7 +230,10 @@ var ServicesMixin = {
|
||||
action: action,
|
||||
options: options,
|
||||
on_success: resolve,
|
||||
on_fail: reject,
|
||||
on_fail: (reason) => {
|
||||
reject(reason);
|
||||
return "alreadyThrown"
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -282,10 +282,11 @@ export function makeLegacyCrashManagerService(legacyEnv) {
|
||||
|
||||
export function wrapSuccessOrFail(promise, { on_success, on_fail } = {}) {
|
||||
return promise.then(on_success || (() => {})).catch((reason) => {
|
||||
let alreadyThrown = false;
|
||||
if (on_fail) {
|
||||
on_fail(reason);
|
||||
alreadyThrown = on_fail(reason) === "alreadyThrown";
|
||||
}
|
||||
if (reason instanceof Error) {
|
||||
if (reason instanceof Error && !alreadyThrown) {
|
||||
throw reason;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
odoo.define('web.mixins_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const AbstractAction = require("web.AbstractAction");
|
||||
const core = require("web.core");
|
||||
var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
const { dialogService } = require('@web/core/dialog/dialog_service');
|
||||
const { errorService } = require("@web/core/errors/error_service");
|
||||
const { registry } = require('@web/core/registry');
|
||||
const { nextTick, patchWithCleanup } = require('@web/../tests/helpers/utils');
|
||||
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
|
||||
|
||||
QUnit.module('core', {}, function () {
|
||||
|
||||
QUnit.module('mixins');
|
||||
@@ -29,7 +37,40 @@ QUnit.module('core', {}, function () {
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('checks that the error generated by a do_action opens one dialog', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
window.addEventListener("unhandledrejection", async (ev) => {
|
||||
ev.preventDefault();
|
||||
});
|
||||
patchWithCleanup(QUnit, {
|
||||
onUnhandledRejection: () => {},
|
||||
});
|
||||
|
||||
const serviceRegistry = registry.category("services");
|
||||
serviceRegistry.add("dialog", dialogService);
|
||||
serviceRegistry.add("error", errorService);
|
||||
|
||||
const TestAction = AbstractAction.extend({
|
||||
on_attach_callback() {
|
||||
this.do_action({
|
||||
id: 1,
|
||||
type: "ir.actions.server",
|
||||
})
|
||||
},
|
||||
});
|
||||
core.action_registry.add("TestAction", TestAction);
|
||||
|
||||
const mockRPC = (route) => {
|
||||
if (route === "/web/action/run") {
|
||||
throw new Error("This error should be throw only once");
|
||||
}
|
||||
};
|
||||
const webClient = await createWebClient({mockRPC});
|
||||
await doAction(webClient, "TestAction");
|
||||
await nextTick();
|
||||
assert.containsOnce(webClient, ".o_dialog");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user