mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Clear module cache when require'ing an es module with TLA throws (#24389)
### What does this PR do? Fixes #24387 ### How did you verify your code works? --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Marko Vejnovic <marko@bun.com>
This commit is contained in:
@@ -215,6 +215,8 @@ export function loadEsmIntoCjs(resolvedSpecifier: string) {
|
||||
if (state < $ModuleLink && $isPromise(fetch)) {
|
||||
// This will probably never happen, but just in case
|
||||
if (($getPromiseInternalField(fetch, $promiseFieldFlags) & $promiseStateMask) === $promiseStatePending) {
|
||||
registry.$delete(resolvedSpecifier);
|
||||
|
||||
throw new TypeError(`require() async module "${key}" is unsupported. use "await import()" instead.`);
|
||||
}
|
||||
|
||||
@@ -231,6 +233,8 @@ export function loadEsmIntoCjs(resolvedSpecifier: string) {
|
||||
let state = flags & $promiseStateMask;
|
||||
// this branch should never happen, but just to be safe
|
||||
if (state === $promiseStatePending || (reactionsOrResult && $isPromise(reactionsOrResult))) {
|
||||
registry.$delete(resolvedSpecifier);
|
||||
|
||||
throw new TypeError(`require() async module "${key}" is unsupported. use "await import()" instead.`);
|
||||
} else if (state === $promiseStateRejected) {
|
||||
if (!reactionsOrResult?.message) {
|
||||
@@ -282,6 +286,8 @@ export function loadEsmIntoCjs(resolvedSpecifier: string) {
|
||||
|
||||
var linkAndEvaluateResult = loader.linkAndEvaluateModule(resolvedSpecifier, undefined);
|
||||
if (linkAndEvaluateResult && $isPromise(linkAndEvaluateResult)) {
|
||||
registry.$delete(resolvedSpecifier);
|
||||
|
||||
// if you use top-level await, or any dependencies use top-level await, then we throw here
|
||||
// this means the module will still actually load eventually, but that's okay.
|
||||
throw new TypeError(
|
||||
|
||||
23
test/regression/issue/24387.test.ts
Normal file
23
test/regression/issue/24387.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
import { join } from "path";
|
||||
|
||||
test("regression: require()ing a module with TLA should error and then wipe the module cache, so that importing it again works", async () => {
|
||||
const proc = Bun.spawn({
|
||||
cmd: [bunExe(), "run", "--smol", join(import.meta.dir, "24387", "entry.js")],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const { stdout, stderr } = proc;
|
||||
|
||||
expect(await stderr.text()).toBe("");
|
||||
expect(await stdout.text()).toMatchInlineSnapshot(`
|
||||
"require() async module "<the module>" is unsupported. use "await import()" instead.
|
||||
Module {
|
||||
foo: 67,
|
||||
}
|
||||
"
|
||||
`);
|
||||
expect(await proc.exited).toBe(0);
|
||||
});
|
||||
12
test/regression/issue/24387/entry.js
Normal file
12
test/regression/issue/24387/entry.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// @bun
|
||||
var { require } = import.meta;
|
||||
const entrypointPath = "./p.js";
|
||||
let listener;
|
||||
try {
|
||||
listener = await require(entrypointPath);
|
||||
} catch (e) {
|
||||
console.log(e.message.replace(require.resolve(entrypointPath), "<the module>"));
|
||||
listener = await import(entrypointPath);
|
||||
}
|
||||
for (let i = 0; i < 5; i++) if (listener.default) listener = listener.default;
|
||||
console.log(listener);
|
||||
2
test/regression/issue/24387/p.js
Normal file
2
test/regression/issue/24387/p.js
Normal file
@@ -0,0 +1,2 @@
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
export const foo = 67;
|
||||
Reference in New Issue
Block a user