Przeglądaj źródła

fix(code-runtime): contain hostile boundary failures

Tianyi Cui 2 miesięcy temu
rodzic
commit
71e0eeac40

+ 5 - 1
packages/code-runtime/code-runtime-worker/src/runtime-host.ts

@@ -49,7 +49,11 @@ export type RuntimeBindingReply =
  * @returns the caller-facing diagnostic text.
  */
 export function runtimeErrorMessage(error: unknown): string {
-  return error instanceof Error ? error.message : String(error)
+  try {
+    return error instanceof Error ? error.message : String(error)
+  } catch {
+    return 'binding rejected with an unrenderable value'
+  }
 }
 
 /**

+ 21 - 0
packages/code-runtime/code-runtime-worker/tests/runtime.spec.ts

@@ -597,6 +597,27 @@ describe('WorkerCodeRuntime — hostile programs (real workers)', () => {
     expect(result.value).toEqual({ name: 'ToolCallError', toolName: 'bad', message: 'binding resolution must be lossless JSON' })
   })
 
+  it('contains binding rejections whose thrown values cannot be rendered', async () => {
+    const { runtime } = await setup()
+    const result = await runtime.run({
+      program: 'try { await tools.bad({}) } catch (error) { return { name: error.name, toolName: error.toolName, message: error.message } }',
+      bindings: tools({
+        bad: async () => {
+          const hostile = new Error('hidden')
+          Object.defineProperty(hostile, 'message', {
+            get() { throw new Error('message getter failed') },
+          })
+          throw hostile
+        },
+      }),
+    })
+    expect(result.value).toEqual({
+      name: 'ToolCallError',
+      toolName: 'bad',
+      message: 'binding rejected with an unrenderable value',
+    })
+  })
+
   it('rejects lossy binding arguments in the worker before invoking the host binding', async () => {
     const { runtime } = await setup()
     let calls = 0