diff --git a/sdk/src/query-gsd-tools-runtime.ts b/sdk/src/query-gsd-tools-runtime.ts index 22a00f4fb..4099c4de1 100644 --- a/sdk/src/query-gsd-tools-runtime.ts +++ b/sdk/src/query-gsd-tools-runtime.ts @@ -7,8 +7,7 @@ import { QuerySubprocessAdapter } from './query-subprocess-adapter.js'; import { QueryNativeDirectAdapter } from './query-native-direct-adapter.js'; import { QueryNativeHotpathAdapter } from './query-native-hotpath-adapter.js'; import { formatQueryRawOutput } from './query-raw-output-projection.js'; -import { failureToolsError, timeoutToolsError } from './query-tools-error-factory.js'; -import type { QueryNativeErrorFactory, QueryToolsErrorFactory } from './query-tools-error-seam.js'; +import { createQueryNativeErrorFactory, createQueryToolsErrorFactory } from './query-tools-error-factory.js'; export interface GSDToolsRuntime { registry: ReturnType; @@ -29,12 +28,7 @@ export function createGSDToolsRuntime(opts: { }): GSDToolsRuntime { const registry = createRegistry(opts.eventStream, opts.sessionId); - const queryToolsErrorFactory: QueryToolsErrorFactory = { - createTimeoutError: (message, command, args, stderr, timeoutMs) => - timeoutToolsError(message, command, args, stderr, timeoutMs), - createFailureError: (message, command, args, exitCode, stderr) => - failureToolsError(message, command, args, exitCode, stderr), - }; + const queryToolsErrorFactory = createQueryToolsErrorFactory(); const subprocessAdapter = new QuerySubprocessAdapter({ projectDir: opts.projectDir, @@ -44,12 +38,7 @@ export function createGSDToolsRuntime(opts: { ...queryToolsErrorFactory, }); - const nativeErrorFactory: QueryNativeErrorFactory = { - createNativeTimeoutError: (message, command, args) => - timeoutToolsError(message, command, args, '', opts.timeoutMs), - createNativeFailureError: (message, command, args, cause) => - failureToolsError(message, command, args, 1, '', cause), - }; + const nativeErrorFactory = createQueryNativeErrorFactory(opts.timeoutMs); const nativeDirectAdapter = new QueryNativeDirectAdapter({ timeoutMs: opts.timeoutMs, diff --git a/sdk/src/query-tools-error-factory.test.ts b/sdk/src/query-tools-error-factory.test.ts index dad1075e6..84f63a058 100644 --- a/sdk/src/query-tools-error-factory.test.ts +++ b/sdk/src/query-tools-error-factory.test.ts @@ -1,6 +1,8 @@ import { describe, expect, it } from 'vitest'; import { ErrorClassification, GSDError } from './errors.js'; import { + createQueryNativeErrorFactory, + createQueryToolsErrorFactory, failureToolsError, timeoutToolsError, toToolsErrorFromUnknown, @@ -22,4 +24,14 @@ describe('query tools error factory', () => { const err = toToolsErrorFromUnknown('state', ['load'], new Error('gsd-tools timed out after 50ms: state load')); expect(err.classification).toEqual({ kind: 'timeout', timeoutMs: 50 }); }); + + it('builds subprocess/native error factories', () => { + const toolsFactory = createQueryToolsErrorFactory(); + const nativeFactory = createQueryNativeErrorFactory(777); + + expect(toolsFactory.createFailureError('x', 'state', ['load'], 1, '').classification).toEqual({ kind: 'failure' }); + expect(toolsFactory.createTimeoutError('x', 'state', ['load'], '', 123).classification).toEqual({ kind: 'timeout', timeoutMs: 123 }); + expect(nativeFactory.createNativeTimeoutError('x', 'state', ['load']).classification).toEqual({ kind: 'timeout', timeoutMs: 777 }); + expect(nativeFactory.createNativeFailureError('x', 'state', ['load'], new Error('boom')).classification).toEqual({ kind: 'failure' }); + }); }); diff --git a/sdk/src/query-tools-error-factory.ts b/sdk/src/query-tools-error-factory.ts index 838f51381..620a9fe85 100644 --- a/sdk/src/query-tools-error-factory.ts +++ b/sdk/src/query-tools-error-factory.ts @@ -1,6 +1,7 @@ import { GSDError, exitCodeFor } from './errors.js'; import { GSDToolsError } from './gsd-tools-error.js'; import { errorMessage, toFailureSignal } from './query-failure-classification.js'; +import type { QueryNativeErrorFactory, QueryToolsErrorFactory } from './query-tools-error-seam.js'; export function timeoutToolsError(message: string, command: string, args: string[], stderr = '', timeoutMs?: number): GSDToolsError { return GSDToolsError.timeout(message, command, args, stderr, timeoutMs); @@ -29,3 +30,21 @@ export function toToolsErrorFromUnknown(command: string, args: string[], err: un } return failureToolsError(msg, command, args, 1, '', err instanceof Error ? err : undefined); } + +export function createQueryToolsErrorFactory(): QueryToolsErrorFactory { + return { + createTimeoutError: (message, command, args, stderr, timeoutMs) => + timeoutToolsError(message, command, args, stderr, timeoutMs), + createFailureError: (message, command, args, exitCode, stderr) => + failureToolsError(message, command, args, exitCode, stderr), + }; +} + +export function createQueryNativeErrorFactory(defaultTimeoutMs: number): QueryNativeErrorFactory { + return { + createNativeTimeoutError: (message, command, args) => + timeoutToolsError(message, command, args, '', defaultTimeoutMs), + createNativeFailureError: (message, command, args, cause) => + failureToolsError(message, command, args, 1, '', cause), + }; +}