[FIX] components: wrap onWillRender/onRendered hooks instead of renderFn

Previously, we were wrapping the entire renderFn in a try/catch, causing
errors during template execution to be caught and wrapped by
onWillRender/onRendered which is undesirable. Now we only wrap the hook
that's being registered.
This commit is contained in:
Samuel Degueldre
2022-03-08 09:37:39 +01:00
committed by Géry Debongnie
parent 14d2328c88
commit 67f86a4ab8
3 changed files with 67 additions and 6 deletions
@@ -1156,6 +1156,19 @@ exports[`errors and promises errors in mounted and in willUnmount 1`] = `
}"
`;
exports[`errors and promises errors in onWillRender/onRender aren't wrapped more than once 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block1 = createBlock(\`<div>abc</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`errors and promises errors in rerender 1`] = `
"function anonymous(bdom, helpers
) {
+46
View File
@@ -5,6 +5,8 @@ import {
onPatched,
onWillPatch,
onWillStart,
onWillRender,
onRendered,
onWillUnmount,
useState,
xml,
@@ -199,6 +201,50 @@ describe("errors and promises", () => {
expect(mockConsoleWarn).toBeCalledTimes(1);
});
test("errors in onWillRender/onRender aren't wrapped more than once", async () => {
class App extends Component {
static template = xml`<div>abc</div>`;
setup() {
onWillRender(() => {
throw new Error("boom in onWillRender");
});
onRendered(() => {
throw new Error("boom in onRendered");
});
}
}
let error: Error;
try {
await mount(App, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe(
`The following error occurred in onWillRender: "boom in onWillRender"`
);
});
test("error while rendering component isn't wrapped by onWillRender/onRendered", async () => {
class App extends Component {
static template = xml`<div t-att-class="{ 'invalid: 5 }">abc</div>`;
setup() {
onWillRender(() => {});
onRendered(() => {});
}
}
let error: Error;
try {
await mount(App, fixture, { test: true });
} catch (e) {
error = e as Error;
}
expect(error!).toBeDefined();
expect(error!.message).toBe("Tokenizer error: could not tokenize `{ 'invalid: 5 }`");
});
test("an error in willPatch call will reject the render promise", async () => {
class Root extends Component {
static template = xml`<div><t t-esc="val"/></div>`;