Skip to content

Commit 1dbc5a0

Browse files
committed
Improve “Illegal invocation” error messages
1 parent 7d45dfc commit 1dbc5a0

File tree

4 files changed

+478
-342
lines changed

4 files changed

+478
-342
lines changed

lib/constructs/attribute.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Attribute {
2929

3030
let brandCheck = `
3131
if (!exports.is(esValue)) {
32-
throw new TypeError("Illegal invocation");
32+
throw new TypeError("'$KEYWORD$ ${this.idl.name}' called on an object that does not implement interface ${this.interface.name}.");
3333
}
3434
`;
3535
let getterBody = `return utils.tryWrapperForImpl(esValue[implSymbol]["${this.idl.name}"]);`;
@@ -78,11 +78,13 @@ class Attribute {
7878
addMethod(this.idl.name, [], `
7979
${promiseHandlingBefore}
8080
const esValue = this !== null && this !== undefined ? this : globalObject;
81-
${brandCheck}
81+
${brandCheck.replace("$KEYWORD$", "get")}
8282
${getterBody}
8383
${promiseHandlingAfter}
8484
`, "get", { configurable });
8585

86+
brandCheck = brandCheck.replace("$KEYWORD$", "set");
87+
8688
if (!this.idl.readonly) {
8789
if (async) {
8890
throw new Error(`Illegal promise-typed attribute "${this.idl.name}" in interface "${this.interface.idl.name}"`);
@@ -159,7 +161,7 @@ class Attribute {
159161
addMethod("toString", [], `
160162
const esValue = this;
161163
if (!exports.is(esValue)) {
162-
throw new TypeError("Illegal invocation");
164+
throw new TypeError("'toString' called on an object that does not implement interface ${this.interface.name}.");
163165
}
164166
165167
${getterBody}

lib/constructs/iterable.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class Iterable {
2020

2121
generateFunction(key, kind) {
2222
this.interface.addMethod(this.interface.defaultWhence, key, [], `
23-
if (!this || !exports.is(this)) {
24-
throw new TypeError("Illegal invocation");
23+
if (!exports.is(this)) {
24+
throw new TypeError("'${key}' called on an object that does not implement interface ${this.interface.name}.");
2525
}
2626
return exports.createDefaultIterator(this, "${kind}");
2727
`);
@@ -35,8 +35,8 @@ class Iterable {
3535
this.generateFunction("entries", "key+value");
3636
this.interface.addProperty(whence, Symbol.iterator, `${this.interface.name}.prototype.entries`);
3737
this.interface.addMethod(whence, "forEach", ["callback"], `
38-
if (!this || !exports.is(this)) {
39-
throw new TypeError("Illegal invocation");
38+
if (!exports.is(this)) {
39+
throw new TypeError("'forEach' called on an object that does not implement interface ${this.interface.name}.");
4040
}
4141
if (arguments.length < 1) {
4242
throw new TypeError("Failed to execute 'forEach' on '${this.name}': 1 argument required, " +

lib/constructs/operation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Operation {
8585
str += `
8686
const esValue = this !== null && this !== undefined ? this : globalObject;
8787
if (!exports.is(esValue)) {
88-
throw new TypeError("Illegal invocation");
88+
throw new TypeError("'${this.name}' called on an object that does not implement interface ${this.interface.name}.");
8989
}
9090
`;
9191
}

0 commit comments

Comments
 (0)