From 3a93370ab620634ca5d73292272ee9a690ffbf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Sat, 3 Jul 2021 15:34:20 +0200 Subject: [PATCH] [FIX] component: do not shadow the initial error in some cases Before this commit, the error handling code simply destroyed the application whenever an unhandled error occured in the owl rendering process. This is perfectly fine, except that since the application is potentially corrupted, the destroy code may crash as well. We simply catch those errors to avoid shadowing the main issue. closes #866 --- src/component/fiber.ts | 9 ++++++++- tests/component/error_handling.test.ts | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/component/fiber.ts b/src/component/fiber.ts index ee76c01f..07150a91 100644 --- a/src/component/fiber.ts +++ b/src/component/fiber.ts @@ -355,7 +355,14 @@ export class Fiber { this.root.counter = 0; this.root.error = error; scheduler.flush(); - root.destroy(); + // at this point, the state of the application is corrupted and we could + // have a lot of issues or crashes. So we destroy the application in a try + // catch and swallow these errors because the fiber is already in error, + // and this is the actual issue that needs to be solved, not those followup + // errors. + try { + root.destroy(); + } catch (e) {} } } } diff --git a/tests/component/error_handling.test.ts b/tests/component/error_handling.test.ts index 666da5a3..1af4e9b9 100644 --- a/tests/component/error_handling.test.ts +++ b/tests/component/error_handling.test.ts @@ -586,4 +586,25 @@ describe("component error handling (catchError)", () => { await mount(Parent, { target: fixture }); expect(fixture.innerHTML).toBe("
Error
"); }); + + test("errors in mounted and in willUnmount", async () => { + expect.assertions(1); + class Example extends Component { + static template = xml`
`; + val; + mounted() { + throw new Error("Error in mounted"); + this.val = { foo: "bar" }; + } + willUnmount() { + console.log(this.val.foo); + } + } + + try { + await mount(Example, { target: fixture }); + } catch (e) { + expect(e.message).toBe("Error in mounted"); + } + }); });