diff --git a/src/component/handler.ts b/src/component/handler.ts
index 57af331f..35aece9d 100644
--- a/src/component/handler.ts
+++ b/src/component/handler.ts
@@ -31,9 +31,13 @@ export const mainEventHandler = (data: any, ev: Event, currentTarget?: EventTarg
// We check this rather than data[0] being truthy (or typeof function) so that it crashes
// as expected when there is a handler expression that evaluates to a falsy value
if (Object.hasOwnProperty.call(data, 0)) {
+ const handler = data[0];
+ if (typeof handler !== "function") {
+ throw new Error(`Invalid handler (expected a function, received: '${handler}')`);
+ }
let node = data[1] ? data[1].__owl__ : null;
if (node ? node.status === STATUS.MOUNTED : true) {
- data[0].call(node ? node.component : null, ev);
+ handler.call(node ? node.component : null, ev);
}
}
return stopped;
diff --git a/tests/components/__snapshots__/event_handling.test.ts.snap b/tests/components/__snapshots__/event_handling.test.ts.snap
index 47e73ccf..d6b4e7be 100644
--- a/tests/components/__snapshots__/event_handling.test.ts.snap
+++ b/tests/components/__snapshots__/event_handling.test.ts.snap
@@ -1,5 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`event handling Invalid handler throws an error 1`] = `
+"function anonymous(bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
+
+ let block1 = createBlock(\`\`);
+
+ return function template(ctx, node, key = \\"\\") {
+ let hdlr1 = [ctx['dosomething'], ctx];
+ return block1([hdlr1]);
+ }
+}"
+`;
+
exports[`event handling handler is not called if component is destroyed 1`] = `
"function anonymous(bdom, helpers
) {
diff --git a/tests/components/event_handling.test.ts b/tests/components/event_handling.test.ts
index 2134184a..1e18e47d 100644
--- a/tests/components/event_handling.test.ts
+++ b/tests/components/event_handling.test.ts
@@ -33,6 +33,28 @@ describe("event handling", () => {
expect(fixture.innerHTML).toBe("simple vnode
2");
});
+ test("Invalid handler throws an error", async () => {
+ window.addEventListener(
+ "error",
+ (ev) => {
+ logStep(ev.error.message);
+ ev.preventDefault();
+ },
+ { once: true }
+ );
+
+ class Parent extends Component {
+ static template = xml``;
+
+ doSomething() {}
+ }
+
+ await mount(Parent, fixture);
+ expect([]).toBeLogged();
+ fixture.querySelector("button")!.click();
+ expect(["Invalid handler (expected a function, received: 'undefined')"]).toBeLogged();
+ });
+
test("support for callable expression in event handler", async () => {
class Counter extends Component {
static template = xml`