From 4e308bfdabc6c4369acf668aa848b4072106d768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 18 Jun 2021 11:37:05 +0200 Subject: [PATCH] [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. --- .../src/webclient/actions/action_container.js | 15 ++++++++ .../webclient/actions/error_handling_tests.js | 35 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 addons/web/static/tests/webclient/actions/error_handling_tests.js diff --git a/addons/web/static/src/webclient/actions/action_container.js b/addons/web/static/src/webclient/actions/action_container.js index 7bb144f229d..f6d856902a6 100644 --- a/addons/web/static/src/webclient/actions/action_container.js +++ b/addons/web/static/src/webclient/actions/action_container.js @@ -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` diff --git a/addons/web/static/tests/webclient/actions/error_handling_tests.js b/addons/web/static/tests/webclient/actions/error_handling_tests.js new file mode 100644 index 00000000000..29cb0b27920 --- /dev/null +++ b/addons/web/static/tests/webclient/actions/error_handling_tests.js @@ -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`
`; + 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, ""); + }); +});