diff --git a/src/component/fiber.ts b/src/component/fiber.ts index c6b47bdc..ee76c01f 100644 --- a/src/component/fiber.ts +++ b/src/component/fiber.ts @@ -326,16 +326,30 @@ export class Fiber { const qweb = component.env.qweb; let root = component; - let canCatch = false; - while (component && !(canCatch = !!component.catchError)) { - root = component; - component = component.__owl__.parent!; - } - qweb.trigger("error", error); - if (canCatch) { - component.catchError!(error); - } else { + function handle(error) { + let canCatch = false; + qweb.trigger("error", error); + while (component && !(canCatch = !!component.catchError)) { + root = component; + component = component.__owl__.parent!; + } + if (canCatch) { + try { + component.catchError!(error); + } catch (e) { + root = component; + component = component.__owl__.parent!; + return handle(e); + } + return true; + } + return false; + } + + let isHandled = handle(error); + + if (!isHandled) { // the 3 next lines aim to mark the root fiber as being in error, and // to force it to end, without waiting for its children this.root.counter = 0; diff --git a/tests/component/error_handling.test.ts b/tests/component/error_handling.test.ts index 191c939f..666da5a3 100644 --- a/tests/component/error_handling.test.ts +++ b/tests/component/error_handling.test.ts @@ -1,4 +1,4 @@ -import { Component, Env, STATUS } from "../../src/component/component"; +import { Component, Env, mount, STATUS } from "../../src/component/component"; import { useState } from "../../src/hooks"; import { xml } from "../../src/tags"; import { makeTestEnv, makeTestFixture, nextTick } from "../helpers"; @@ -520,4 +520,70 @@ describe("component error handling (catchError)", () => { expect(error).toBeDefined(); expect(error.message).toBe("Cannot read property 'y' of undefined"); }); + + test("simple catchError", async () => { + class Boom extends Component { + static template = xml`
`; + } + + class Parent extends Component { + static template = xml` +