isolated-vm
isolated-vm copied to clipboard
Minimal representation of isolate code hanging the entire process
For me, the following code hangs the outer node process in 60% of cases. In other cases, it finishes with a top-level error about the unhandled promise. By slightly modifying the code, I can also come up with a version that crashes the outer process with the same top-level error without an opportunity to catch it.
import ivm from 'isolated-vm';
const isolate = new ivm.Isolate();
const context = isolate.createContextSync();
context.evalClosureSync(
`
globalThis.fn = async () => {
await new Promise(res => {
$1.applySync(undefined, [new $0.Reference(res), 0]);
});
new Promise((res, rej) => { rej(new Error("from promise")); });
};
`,
[
/* $0 */
ivm,
/* $1 setTimeout */
new ivm.Reference((cb, ms) => {
setTimeout(() => {
cb.apply(undefined, []);
}, ms);
}),
],
);
const code = `fn()`;
console.log('before first');
try {
await context.eval(code, { promise: true });
} catch (e) {
console.log('error first');
}
console.log('after first');
console.log('before second');
try {
await context.eval(code, { promise: true });
} catch (e) {
console.log('error second');
}
console.log('after second');
console.log('before third');
try {
await context.eval(code, { promise: true });
} catch (e) {
console.log('error third');
}
console.log('after third');
console.log('before fourth');
try {
await context.eval(code, { promise: true });
} catch (e) {
console.log('error fourth');
}
console.log('after fourth');