From 7809236236580edfea2e70a1f02a5c5104ee4222 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Thu, 23 Jul 2026 03:51:15 +0800 Subject: [PATCH] fix(code-runtime): capture worker error intrinsic --- .../code-runtime-worker/src/bootstrap.ts | 17 +++++++++-------- .../code-runtime-worker/tests/runtime.spec.ts | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/code-runtime/code-runtime-worker/src/bootstrap.ts b/packages/code-runtime/code-runtime-worker/src/bootstrap.ts index b654b04fec..aad4b7b2e6 100644 --- a/packages/code-runtime/code-runtime-worker/src/bootstrap.ts +++ b/packages/code-runtime/code-runtime-worker/src/bootstrap.ts @@ -10,6 +10,7 @@ import type { DoneMessage, ReplyMessage, WorkerBootData, WorkerToHost } from './ import { jsonStringBytesUpTo, jsonValueBytesUpTo, truncateJsonStringBytes } from './output-json.ts' import { decodeWorkerJson, encodeWorkerJson, snapshotCodeJsonValue } from './worker-json.ts' +const CapturedError = Error const capturedObjectCreate = Object.create const capturedObjectDefineProperty = Object.defineProperty @@ -77,7 +78,7 @@ export class LogBuffer { if (prefix.length > 0) { const prefixBytes = jsonStringBytesUpTo(prefix, availableBytes) /* v8 ignore next -- truncateJsonStringBytes guarantees the returned prefix fits. */ - if (prefixBytes === undefined) throw new Error('worker output ledger produced an oversized log prefix') + if (prefixBytes === undefined) throw new CapturedError('worker output ledger produced an oversized log prefix') this.bytes += prefixBytes + separatorBytes this.entries += 1 this.sink(prefix) @@ -219,7 +220,7 @@ export function prepareException( ): Omit { let message: string try { - const detail: unknown = error instanceof Error ? error.stack ?? error.message : error + const detail: unknown = error instanceof CapturedError ? error.stack ?? error.message : error message = typeof detail === 'string' ? detail : String(detail) } catch { message = 'program threw an unrenderable value' @@ -244,7 +245,7 @@ export type BindingErrorConstructor = new (memberName: string, message: string) function makeBindingErrorClass( descriptor: { name: string; memberNameProperty: string }, ): BindingErrorConstructor { - return class BindingCallError extends Error { + return class BindingCallError extends CapturedError { constructor(memberName: string, message: string) { super(message) defineBindingErrorField(this, 'name', descriptor.name) @@ -255,7 +256,7 @@ function makeBindingErrorClass( /** Create the namespace-specific rejection for one failed binding call. */ function bindingFailure(errorClass: BindingErrorConstructor | undefined, memberName: string, message: string): Error { - return errorClass ? new errorClass(memberName, message) : new Error(message) + return errorClass ? new errorClass(memberName, message) : new CapturedError(message) } /** @@ -289,10 +290,10 @@ export function wireReplies(port: BootstrapPort, pending: Map { Function.prototype.toString = () => 'mutated'; objectPrototype.get = () => undefined; objectPrototype.constructor = arrayPrototype.constructor = null; - globalThis.Array = globalThis.Buffer = globalThis.Function = globalThis.Number = globalThis.Object = globalThis.Reflect = globalThis.Set = globalThis.String = undefined; + globalThis.Array = globalThis.Buffer = globalThis.Error = globalThis.Function = globalThis.Number = globalThis.Object = globalThis.Reflect = globalThis.Set = globalThis.String = undefined; const echoed = await tools.echo({ request: ['€', 1] }); let failure; try { await tools.fail({}) } catch (error) {