capability: on() without a function says what it got and what to pass

The message read "the handler of TurnOn is a function", which states the
opposite of what went wrong. It is now
  on("TurnOff") got undefined as the handler: pass a function that takes
  the context of the directive
under the endpoint and the interface, as every DeclarationError.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
David 2026-09-28 21:19:31 +00:00
parent 2f6730eb52
commit b083b23ab0
4 changed files with 11 additions and 5 deletions

View file

@ -36,8 +36,9 @@ class Capability {
if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) { if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) {
throw new types_js_1.DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`); throw new types_js_1.DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`);
} }
if (typeof handler !== "function") if (typeof handler !== "function") {
throw new types_js_1.DeclarationError(this, `the handler of ${name} is a function`); throw new types_js_1.DeclarationError(this, `on("${name}") got ${handler === null ? "null" : typeof handler} as the handler: pass a function that takes the context of the directive`);
}
this.handlers.set(name, handler); this.handlers.set(name, handler);
return this; return this;
} }

View file

@ -33,8 +33,9 @@ export class Capability {
if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) { if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) {
throw new DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`); throw new DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`);
} }
if (typeof handler !== "function") if (typeof handler !== "function") {
throw new DeclarationError(this, `the handler of ${name} is a function`); throw new DeclarationError(this, `on("${name}") got ${handler === null ? "null" : typeof handler} as the handler: pass a function that takes the context of the directive`);
}
this.handlers.set(name, handler); this.handlers.set(name, handler);
return this; return this;
} }

View file

@ -101,7 +101,9 @@ export class Capability<P extends Properties = Properties, D extends Directives
if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) { if (name !== "*" && this.descriptor.tier !== 3 && !names.includes(name)) {
throw new DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`); throw new DeclarationError(this, `${name} is not a directive of the interface, which has ${names.join(", ") || "none"}`);
} }
if (typeof handler !== "function") throw new DeclarationError(this, `the handler of ${name} is a function`); if (typeof handler !== "function") {
throw new DeclarationError(this, `on("${name}") got ${handler === null ? "null" : typeof handler} as the handler: pass a function that takes the context of the directive`);
}
this.handlers.set(name, handler); this.handlers.set(name, handler);
return this; return this;
} }

View file

@ -139,6 +139,8 @@ test("on(): \"*\" and onDirective() take what has no handler of its own; a name
assert.deepEqual(called, ["TurnOn TurnOn", "* TurnOff", "device SetBrightness"]); assert.deepEqual(called, ["TurnOn TurnOn", "* TurnOff", "device SetBrightness"]);
assert.throws(() => power.on("Toggle", by("Toggle")), (err) => err instanceof DeclarationError assert.throws(() => power.on("Toggle", by("Toggle")), (err) => err instanceof DeclarationError
&& err.message === "lamp-1: Alexa.PowerController: Toggle is not a directive of the interface, which has TurnOn, TurnOff"); && err.message === "lamp-1: Alexa.PowerController: Toggle is not a directive of the interface, which has TurnOn, TurnOff");
assert.throws(() => power.on("TurnOff"), (err) => err instanceof DeclarationError
&& err.message === "lamp-1: Alexa.PowerController: on(\"TurnOff\") got undefined as the handler: pass a function that takes the context of the directive");
}); });
test("a handler that throws or rejects answers INTERNAL_ERROR, the bridge reports what it threw, and nothing is left unhandled", async () => { test("a handler that throws or rejects answers INTERNAL_ERROR, the bridge reports what it threw, and nothing is left unhandled", async () => {