Skip to content

Commit

Permalink
[wrangler] fix: make sure getPlatformProxy's ctx methods throw il…
Browse files Browse the repository at this point in the history
…legal invocation errors like workerd (#6199)
  • Loading branch information
dario-piotrowicz committed Jul 5, 2024
1 parent 286cdd6 commit 88313e5
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
19 changes: 19 additions & 0 deletions .changeset/plenty-chicken-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"wrangler": patch
---

fix: make sure `getPlatformProxy`'s `ctx` methods throw illegal invocation errors like workerd

in workerd detaching the `waitUntil` and `passThroughOnException` methods from the `ExecutionContext`
object results in them throwing `illegal invocation` errors, such as for example:

```js
export default {
async fetch(_request, _env, { waitUntil }) {
waitUntil(() => {}); // <-- throws an illegal invocation error
return new Response("Hello World!");
},
};
```

make sure that the same behavior is applied to the `ctx` object returned by `getPlatformProxy`
82 changes: 82 additions & 0 deletions fixtures/get-platform-proxy/tests/get-platform-proxy.ctx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,86 @@ describe("getPlatformProxy - ctx", () => {
await dispose();
}
});

describe("detached methods should behave like workerd", () => {
it("destructured methods should throw illegal invocation errors", async () => {
const {
ctx: { waitUntil, passThroughOnException },
dispose,
} = await getPlatformProxy();
try {
expect(() => {
waitUntil(() => {});
}).toThrowError("Illegal invocation");

expect(() => {
passThroughOnException();
}).toThrowError("Illegal invocation");
} finally {
await dispose();
}
});

it("extracted methods should throw illegal invocation errors", async () => {
const { ctx, dispose } = await getPlatformProxy();
const waitUntil = ctx.waitUntil;
const passThroughOnException = ctx.passThroughOnException;

try {
expect(() => {
waitUntil(() => {});
}).toThrowError("Illegal invocation");

expect(() => {
passThroughOnException();
}).toThrowError("Illegal invocation");
} finally {
await dispose();
}
});

it("extracted methods which correctly bind this should not throw illegal invocation errors", async () => {
const { ctx, dispose } = await getPlatformProxy();
const waitUntil = ctx.waitUntil.bind(ctx);
const passThroughOnException = ctx.passThroughOnException;

try {
expect(() => {
waitUntil(() => {});
}).not.toThrowError("Illegal invocation");

expect(() => {
passThroughOnException.apply(ctx, []);
}).not.toThrowError("Illegal invocation");

expect(() => {
passThroughOnException.call(ctx);
}).not.toThrowError("Illegal invocation");
} finally {
await dispose();
}
});

it("extracted methods which incorrectly bind this should throw illegal invocation errors", async () => {
const { ctx, dispose } = await getPlatformProxy();
const waitUntil = ctx.waitUntil.bind({});
const passThroughOnException = ctx.passThroughOnException;

try {
expect(() => {
waitUntil(() => {});
}).toThrowError("Illegal invocation");

expect(() => {
passThroughOnException.apply(5, []);
}).toThrowError("Illegal invocation");

expect(() => {
passThroughOnException.call(new Boolean(), []);
}).toThrowError("Illegal invocation");
} finally {
await dispose();
}
});
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
export class ExecutionContext {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, unused-imports/no-unused-vars
waitUntil(promise: Promise<any>): void {}
passThroughOnException(): void {}
waitUntil(promise: Promise<any>): void {
if (!(this instanceof ExecutionContext)) {
throw new Error("Illegal invocation");
}
}
passThroughOnException(): void {
if (!(this instanceof ExecutionContext)) {
throw new Error("Illegal invocation");
}
}
}

0 comments on commit 88313e5

Please sign in to comment.