[IMP] web: properly handle errors in action controllers

Before this commit, an error in the rendering of a client action or view
would not be properly cleaned: the action container did not catch any
error, so owl would destroy the UI.

With this commit, we simply catch the error, and empty the content of
the action container.
This commit is contained in:
Géry Debongnie
2021-06-18 21:31:34 +02:00
committed by Aaron Bohy
parent 21622ce515
commit 4e308bfdab
2 changed files with 50 additions and 0 deletions
@@ -20,6 +20,21 @@ export class ActionContainer extends Component {
this.env.bus.off("ACTION_MANAGER:UPDATE", this);
super.destroy();
}
catchError() {
this.info = {};
this.render();
// we trigger here the 'MENUS-APP-CHANGED' event to make sure the navbar
// is properly displayed/updated.
this.env.bus.trigger("MENUS:APP-CHANGED");
// we do not rethrow the error here, because the controller component
// already caught the error, and rejected the doAction promise. That
// doAction promise will then trigger an unhandledRejection error, which
// will be displayed by the error service (unless the promise is handled
// by some caller code, but then in that case, it is its own responsibility
// to handle the error properly.
}
}
ActionContainer.components = { ActionDialog };
ActionContainer.template = tags.xml`
@@ -0,0 +1,35 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { createWebClient, doAction, getActionManagerServerData } from "./../helpers";
const { Component, tags } = owl;
let serverData;
const actionRegistry = registry.category("actions");
QUnit.module("ActionManager", (hooks) => {
hooks.beforeEach(() => {
serverData = getActionManagerServerData();
});
QUnit.module("Error handling");
QUnit.test("error in a client action", async function (assert) {
assert.expect(4);
class Boom extends Component {}
Boom.template = tags.xml`<div><t t-esc="a.b.c"/></div>`;
actionRegistry.add("Boom", Boom);
const webClient = await createWebClient({ serverData });
assert.strictEqual(webClient.el.querySelector(".o_action_manager").innerHTML, "");
await doAction(webClient, "1");
assert.ok(webClient.el.querySelector(".o_action_manager").innerHTML !== "");
try {
await doAction(webClient, "Boom");
} catch (e) {
assert.ok(e instanceof TypeError);
}
assert.strictEqual(webClient.el.querySelector(".o_action_manager").innerHTML, "");
});
});