deno
deno copied to clipboard
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Message("missing field `isEval`")'
trafficstars
Reproducible steps
Environment
> deno --version
deno 1.30.0 (release, x86_64-pc-windows-msvc)
v8 10.9.194.5
typescript 4.9.4
OS: Windows_NT x64 10.0.22621 (Windows 11)
- Save the following as
async_to_sync.ts
Code
const workerCode = `
addEventListener("message", invokeUserCode);
async function invokeUserCode(event: Event): Promise<void> {
const [buffer, name, ...args] = (event as MessageEvent).data as [
SharedArrayBuffer,
string,
...unknown[],
];
try {
const view = new Int32Array(buffer);
await (globalThis as unknown as Record<
string,
(...args: unknown[]) => Promise<unknown>
>)[name](
...args,
);
await update();
Atomics.notify(view, 0, 1);
} catch (error) {
console.log("errored", error);
sendErrorJson(error, { buffer });
}
}
function sendErrorJson(
error: unknown,
{ buffer }: { buffer: SharedArrayBuffer },
): void {
const json = JSON.stringify(error, Object.getOwnPropertyNames(error));
const buf = new Uint8Array(buffer, 4);
const encoder = new TextEncoder();
const view = new Int32Array(buffer);
for (let read = 0; read < json.length;) {
const result = encoder.encodeInto(json.slice(read), buf);
view[0] = result.written;
console.log('notify');
Atomics.notify(view, 0, 1);
read += result.read;
console.log('waitAsync, view[0]: {view[0]}');
// waitAsync is usable
// https://github.com/denoland/deno/issues/15358
Atomics.wait(view, 0, result.written);
console.log("waitAsync finish");
}
Atomics.store(view, 0, 0);
Atomics.notify(view, 0, 1);
}
`;
export class AsyncToSync {
readonly #worker: Worker;
constructor(userAsyncCode: string) {
const blob = new Blob([userAsyncCode, workerCode], {
type: "text/typescript",
});
const url = URL.createObjectURL(blob);
// const url = new URL("./async_worker.ts", import.meta.url);
this.#worker = new Worker(url, { type: "module" });
}
run(name: string, ...args: unknown[]): void {
const buffer = new SharedArrayBuffer(1024);
const view = new Int32Array(buffer);
this.#worker.postMessage([buffer, name, args]);
Atomics.wait(view, 0, 0);
console.log("first wait exit");
throwIfError(view, buffer);
console.log("not thrown");
}
terminate(): void {
this.#worker.terminate();
}
}
function throwIfError(view: Int32Array, buffer: SharedArrayBuffer): void {
if (view[0] === 0) {
return;
}
const decoder = new TextDecoder();
const buf = new Uint8Array(buffer, 4, view[0]);
const chunks: string[] = [];
console.log(`throwIfError out view[0]: ${view[0]}`);
while (view[0]) {
chunks.push(decoder.decode(buf));
Atomics.store(view, 0, -1);
Atomics.notify(view, 0, 1);
Atomics.wait(view, 0, -1);
}
const details = JSON.parse(chunks.join(""));
console.log("asdf");
throw Object.assign(new Error(details.message ?? "Worker error"), {
...details,
});
}
if (import.meta.main) {
const userCode = `
async function update(): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, 500));
}`;
const runner = new AsyncToSync(userCode);
console.time("runner");
runner.run("update", 3);
console.timeEnd("runner");
runner.terminate();
}
deno run async_to_sync.ts
Expected behavior
Never panick.
Actual behavior
deno run .\src\async_to_sync.ts
errored TypeError: globalThis[name] is not a function
at invokeUserCode (blob:null/3db6d11d-481c-4ab0-9bd5-2f327b1d3e04:18:13)
at innerInvokeEventListeners (deno:ext/web/02_event.js:776:9)
at invokeEventListeners (deno:ext/web/02_event.js:816:7)
at dispatch (deno:ext/web/02_event.js:685:11)
at dispatchEvent (deno:ext/web/02_event.js:1066:14)
at pollForMessages (deno:runtime/js/99_main.js:159:9)
notify
waitAsync, view[0]: {view[0]}
first wait exit
throwIfError out view[0]: 516
waitAsync finish
asdf
============================================================
Deno has panicked. This is a bug in Deno. Please report this
at https://github.com/denoland/deno/issues/new.
If you can reliably reproduce this panic, include the
reproduction steps and re-run with the RUST_BACKTRACE=1 env
var set and include the backtrace in your report.
Platform: windows x86_64
Version: 1.30.0
Args: ["C:\\ProgramData\\chocolatey\\lib\\deno\\deno.exe", "run", ".\\src\\async_to_sync.ts"]
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Message("missing field `isEval`")', core\error.rs:377:71
stack backtrace:
0: 0x7ff7b136e936 - napi_release_threadsafe_function
1: 0x7ff7b042006b - napi_release_threadsafe_function
2: 0x7ff7b1348efa - napi_release_threadsafe_function
3: 0x7ff7b1372cbb - napi_release_threadsafe_function
4: 0x7ff7b13728b1 - napi_release_threadsafe_function
5: 0x7ff7b13724bb - napi_release_threadsafe_function
6: 0x7ff7b03241ac - napi_fatal_error
7: 0x7ff7b1373508 - napi_release_threadsafe_function
8: 0x7ff7b1373275 - napi_release_threadsafe_function
9: 0x7ff7b13731bf - napi_release_threadsafe_function
10: 0x7ff7b1373194 - napi_release_threadsafe_function
11: 0x7ff7b2620d55 - CrashForExceptionInNonABICompliantCodeRange
12: 0x7ff7b2621033 - CrashForExceptionInNonABICompliantCodeRange
13: 0x7ff7b053aa81 - napi_release_threadsafe_function
14: 0x7ff7b063d3ac - napi_release_threadsafe_function
15: 0x7ff7b0650ad2 - napi_release_threadsafe_function
16: 0x7ff7b0637684 - napi_release_threadsafe_function
17: 0x7ff7b009d39a - napi_cancel_async_work
18: 0x7ff7b00cbdb1 - napi_cancel_async_work
19: 0x7ff7b0087a1c - napi_cancel_async_work
20: 0x7ff7b004da8d - napi_cancel_async_work
21: 0x7ff7b01052ca - napi_cancel_async_work
22: 0x7ff7b02c4f60 - napi_fatal_error
23: 0x7ff7b0305a76 - napi_fatal_error
24: 0x7ff7b03296bd - napi_fatal_error
25: 0x7ff7b0050fb1 - napi_cancel_async_work
26: 0x7ff7afe8569e - <unknown>
27: 0x7ff7b0324da1 - napi_fatal_error
28: 0x7ff7afecfb33 - <unknown>
29: 0x7ff7b039f524 - napi_release_threadsafe_function
30: 0x7ff7b25d386c - CrashForExceptionInNonABICompliantCodeRange
31: 0x7ffc2b7126bd - BaseThreadInitThunk
32: 0x7ffc2d8edfb8 - RtlUserThreadStart