mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] component: display nice error for wrong child component
If you declare a child component which is not actually a Component,
the error message is not very friendly and not very helpfull to find
what happens and which child component is wrong.
```
const ChildComponent = "not a component constructor";
class MyComponent extends Component {
static components = { ChildComponent };
}
```
This commit improves the type declaration for those working with Typescript
and adds a runtime check for javascript codebases
This commit is contained in:
committed by
Géry Debongnie
parent
d09771b04b
commit
5c71744e19
@@ -10,6 +10,7 @@ interface StaticComponentProperties {
|
|||||||
template: string;
|
template: string;
|
||||||
defaultProps?: any;
|
defaultProps?: any;
|
||||||
props?: any;
|
props?: any;
|
||||||
|
components?: { [componentName: string]: ComponentConstructor };
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ComponentConstructor<P extends Props = any, E = any> = (new (
|
export type ComponentConstructor<P extends Props = any, E = any> = (new (
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ export function component<P extends object>(
|
|||||||
C = parent.constructor.components[name as any];
|
C = parent.constructor.components[name as any];
|
||||||
if (!C) {
|
if (!C) {
|
||||||
throw new Error(`Cannot find the definition of component "${name}"`);
|
throw new Error(`Cannot find the definition of component "${name}"`);
|
||||||
|
} else if (!(C.prototype instanceof Component)) {
|
||||||
|
throw new Error(`"${name}" is not a Component. It must inherit from the Component class`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node = new ComponentNode(C, props, ctx.app, ctx, key);
|
node = new ComponentNode(C, props, ctx.app, ctx, key);
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`basics display a nice error if a component is not a component 1`] = `
|
||||||
|
"function anonymous(bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return component(\`SomeComponent\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`basics display a nice error if it cannot find component (in dev mode) 1`] = `
|
exports[`basics display a nice error if it cannot find component (in dev mode) 1`] = `
|
||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -102,6 +102,25 @@ describe("basics", () => {
|
|||||||
expect(mockConsoleWarn).toBeCalledTimes(1);
|
expect(mockConsoleWarn).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("display a nice error if a component is not a component", async () => {
|
||||||
|
function notAComponentConstructor() {}
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`<SomeComponent />`;
|
||||||
|
static components = { SomeComponent: notAComponentConstructor };
|
||||||
|
}
|
||||||
|
let error: Error;
|
||||||
|
try {
|
||||||
|
// @ts-expect-error
|
||||||
|
await mount(Parent, fixture);
|
||||||
|
} catch (e) {
|
||||||
|
error = e as Error;
|
||||||
|
}
|
||||||
|
expect(error!).toBeDefined();
|
||||||
|
expect(error!.message).toBe(
|
||||||
|
'"SomeComponent" is not a Component. It must inherit from the Component class'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("simple catchError", async () => {
|
test("simple catchError", async () => {
|
||||||
class Boom extends Component {
|
class Boom extends Component {
|
||||||
static template = xml`<div t-esc="a.b.c"/>`;
|
static template = xml`<div t-esc="a.b.c"/>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user