diff --git a/dist-exe/cc-web-bun-linux-x64-baseline.tar.gz b/dist-exe/cc-web-bun-linux-x64-baseline.tar.gz index 4ef0dff..7bdad05 100644 Binary files a/dist-exe/cc-web-bun-linux-x64-baseline.tar.gz and b/dist-exe/cc-web-bun-linux-x64-baseline.tar.gz differ diff --git a/lib/javascript-session-runtime.js b/lib/javascript-session-runtime.js index 8dd65c7..3b9995c 100644 --- a/lib/javascript-session-runtime.js +++ b/lib/javascript-session-runtime.js @@ -124,6 +124,16 @@ const CONVERSATION_STATUSES = new Set(['running', 'waiting_for_children', 'idle' const EVENT_POLL_INTERVAL_MS = 100; const IDLE_EVENT_STABILITY_MS = 250; +function errorFromPayload(payload) { + const error = new Error(String(payload?.message || payload?.code || 'ccweb 脚本调用失败')); + error.code = String(payload?.code || 'script_call_failed'); + error.details = payload && typeof payload === 'object' ? { ...payload } : {}; + delete error.details.ok; + delete error.details.code; + delete error.details.message; + return error; +} + function localError(code, message, details = {}) { const error = new Error(message); error.code = code; diff --git a/scripts/javascript-session-runtime-unit.js b/scripts/javascript-session-runtime-unit.js index e1ef210..7f55254 100644 --- a/scripts/javascript-session-runtime-unit.js +++ b/scripts/javascript-session-runtime-unit.js @@ -67,7 +67,9 @@ async function main() { response = { ok: true, conversationId: payload.sourceSessionId }; break; case 'ccweb_script_get_last_message': - response = { ok: true, conversationId: payload.args.conversationId, message: '服务端最后消息' }; + response = payload.args.conversationId === 'error-test' + ? { ok: false, code: 'conversation_not_found', message: '目标对话不存在。', conversationId: 'error-test' } + : { ok: true, conversationId: payload.args.conversationId, message: '服务端最后消息' }; break; case 'ccweb_script_get_conversation_status': statusCallCount += 1; @@ -156,6 +158,24 @@ async function main() { assert.equal(succeeded.stderr, ''); assert.equal(notifications.length, 0); + assert.equal(runtime.writeScript({ + name: 'error.js', + content: [ + "import { getLastMessage } from '@ccweb/session';", + "try { await getLastMessage('error-test'); } catch (error) {", + " console.log(JSON.stringify({ name: error.name, code: error.code, message: error.message, details: error.details }));", + '}', + ].join('\n'), + }, sourceId).ok, true); + const errorStart = runtime.runScript({ name: 'error.js' }, sourceId); + const errorRun = await waitForRun(runtime, sourceId, errorStart.runId, (run) => run.status === 'succeeded'); + assert.equal(errorRun.exitCode, 0); + const errorResult = JSON.parse(errorRun.stdout.trim()); + assert.equal(errorResult.name, 'Error'); + assert.equal(errorResult.code, 'conversation_not_found'); + assert.equal(errorResult.message, '目标对话不存在。'); + assert.equal(errorResult.details.conversationId, 'error-test'); + assert.equal(runtime.writeScript({ name: 'failed.js', content: "console.error('expected failure'); process.exit(3);" }, sourceId).ok, true); const failedStart = runtime.runScript({ name: 'failed.js' }, sourceId); const failed = await waitForRun(runtime, sourceId, failedStart.runId, (run) => run.status === 'failed');