mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: error handling in class inheritance
Before this commit, class inheritance when using the onError hook was unclear nay wrong. After this commit, error handlers are called from the bottom up in the inheritance hierarchy. If a handler doesn't rethrow the error, the handling stops there and no other handler is called. If a handler does rethrow, the handlers declared in a parent class are executed.
This commit is contained in:
committed by
Aaron Bohy
parent
e91e50a812
commit
c1a973a4d8
@@ -870,4 +870,91 @@ describe("can catch errors", () => {
|
||||
await mount(Parent, fixture);
|
||||
expect(fixture.innerHTML).toBe("<div>Error</div>");
|
||||
});
|
||||
|
||||
test("onError in class inheritance is not called if no rethrown", async () => {
|
||||
const steps: string[] = [];
|
||||
|
||||
class Abstract extends Component {
|
||||
static template = xml`<div>
|
||||
<t t-if="!state.error">
|
||||
<t t-esc="this.will.crash" />
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="state.error"/>
|
||||
</t>
|
||||
</div>`;
|
||||
state: any;
|
||||
setup() {
|
||||
this.state = useState({});
|
||||
onError(() => {
|
||||
steps.push("Abstract onError");
|
||||
this.state.error = "Abstract";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Concrete extends Abstract {
|
||||
setup() {
|
||||
super.setup();
|
||||
onError(() => {
|
||||
steps.push("Concrete onError");
|
||||
this.state.error = "Concrete";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Concrete };
|
||||
static template = xml`<Concrete />`;
|
||||
}
|
||||
|
||||
await mount(Parent, fixture);
|
||||
|
||||
expect(steps).toStrictEqual(["Concrete onError"]);
|
||||
expect(fixture.innerHTML).toBe("<div>Concrete</div>");
|
||||
});
|
||||
|
||||
test("onError in class inheritance is called if rethrown", async () => {
|
||||
const steps: string[] = [];
|
||||
|
||||
class Abstract extends Component {
|
||||
static template = xml`<div>
|
||||
<t t-if="!state.error">
|
||||
<t t-esc="this.will.crash" />
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="state.error"/>
|
||||
</t>
|
||||
</div>`;
|
||||
state: any;
|
||||
setup() {
|
||||
this.state = useState({});
|
||||
onError(() => {
|
||||
steps.push("Abstract onError");
|
||||
this.state.error = "Abstract";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Concrete extends Abstract {
|
||||
setup() {
|
||||
super.setup();
|
||||
onError((error) => {
|
||||
steps.push("Concrete onError");
|
||||
this.state.error = "Concrete";
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Concrete };
|
||||
static template = xml`<Concrete />`;
|
||||
}
|
||||
|
||||
await mount(Parent, fixture);
|
||||
|
||||
expect(steps).toStrictEqual(["Concrete onError", "Abstract onError"]);
|
||||
expect(fixture.innerHTML).toBe("<div>Abstract</div>");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user