[FIX] component: display correct error in some case

It could happen that a component would crash. But then, the __render
code tried to copy the class properties into the vnode, which does not
exist, creating a new error.

So, the solution is to process the classObj only in the successful part
of the render call, which then will not crash, so the normal error
handling will occur.
This commit is contained in:
Géry Debongnie
2019-11-20 13:19:00 +01:00
committed by aab-odoo
parent 2e3e8cd603
commit 27b4eece66
2 changed files with 28 additions and 7 deletions
+7 -7
View File
@@ -597,6 +597,13 @@ export class Component<T extends Env, Props extends {}> {
throw new Error(`Rendering '${this.constructor.name}' did not return anything`);
}
fiber.vnode = vnode;
// we apply here the class information described on the component by the
// template (so, something like <MyComponent class="..."/>) to the actual
// root vnode
if (__owl__.classObj) {
const data = vnode.data!;
data.class = Object.assign(data.class || {}, __owl__.classObj);
}
} catch (e) {
error = e;
}
@@ -604,13 +611,6 @@ export class Component<T extends Env, Props extends {}> {
__owl__.observer.allowMutations = true;
}
// we apply here the class information described on the component by the
// template (so, something like <MyComponent class="..."/>) to the actual
// root vnode
if (__owl__.classObj) {
const data = fiber.vnode!.data!;
data.class = Object.assign(data.class || {}, __owl__.classObj);
}
fiber.root.counter--;
fiber.isRendered = true;
if (error) {
+21
View File
@@ -1718,6 +1718,27 @@ describe("class and style attributes with t-component", () => {
expect(fixture.innerHTML).toBe(`<div><div style="font-size: 30px;"></div></div>`);
});
test("error in subcomponent with class", async () => {
class Child extends Widget {
static template = xml`<div t-esc="this.will.crash"/>`;
}
class ParentWidget extends Widget {
static template = xml`<div><Child class="a"/></div>`;
static components = { Child };
}
const widget = new ParentWidget();
let error;
try {
await widget.mount(fixture);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.message).toBe("Cannot read property 'crash' of undefined");
expect(fixture.innerHTML).toBe("");
});
});
describe("other directives with t-component", () => {