From 7298a76b20067abb3789ead90e4854d40ba190cf Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 4 May 2026 19:58:20 -0400 Subject: [PATCH] refactor: centralize dispatch error projection from failure signals --- sdk/src/query/query-dispatch-error-mapper.ts | 11 +++------- sdk/src/query/query-error-taxonomy.test.ts | 8 ++++++++ sdk/src/query/query-error-taxonomy.ts | 21 +++++++++++++++++++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/sdk/src/query/query-dispatch-error-mapper.ts b/sdk/src/query/query-dispatch-error-mapper.ts index 5d4a725af..bd377be19 100644 --- a/sdk/src/query/query-dispatch-error-mapper.ts +++ b/sdk/src/query/query-dispatch-error-mapper.ts @@ -1,6 +1,6 @@ import type { QueryDispatchError, QueryDispatchResult } from './query-dispatch-contract.js'; import { toFailureSignal } from '../query-failure-classification.js'; -import { fallbackFailureError, nativeFailureError, nativeTimeoutError } from './query-error-taxonomy.js'; +import { fallbackDispatchErrorFromSignal, nativeDispatchErrorFromSignal } from './query-error-taxonomy.js'; import { dispatchFailure } from './query-dispatch-result-builder.js'; export function toDispatchFailure( @@ -11,14 +11,9 @@ export function toDispatchFailure( } export function mapNativeDispatchError(error: unknown, command: string, args: string[]): QueryDispatchError { - const signal = toFailureSignal(error); - if (signal.kind === 'timeout') { - return nativeTimeoutError({ message: signal.message, command, args, timeoutMs: signal.timeoutMs }); - } - return nativeFailureError({ message: signal.message, command, args }); + return nativeDispatchErrorFromSignal(toFailureSignal(error), command, args); } export function mapFallbackDispatchError(error: unknown, command: string, args: string[]): QueryDispatchError { - const signal = toFailureSignal(error); - return fallbackFailureError({ message: signal.message, command, args, backend: 'cjs' }); + return fallbackDispatchErrorFromSignal(toFailureSignal(error), command, args); } diff --git a/sdk/src/query/query-error-taxonomy.test.ts b/sdk/src/query/query-error-taxonomy.test.ts index 3f900d736..823e3e7f0 100644 --- a/sdk/src/query/query-error-taxonomy.test.ts +++ b/sdk/src/query/query-error-taxonomy.test.ts @@ -1,7 +1,9 @@ import { describe, it, expect } from 'vitest'; import { + fallbackDispatchErrorFromSignal, fallbackFailureError, internalError, + nativeDispatchErrorFromSignal, nativeFailureError, nativeTimeoutError, unknownCommandError, @@ -28,4 +30,10 @@ describe('query-error-taxonomy', () => { expect(validationError({ message: 'bad', details: { r: 'x' } }).kind).toBe('validation_error'); expect(internalError({ message: 'bad' }).kind).toBe('internal_error'); }); + + it('projects dispatch errors from failure signals', () => { + expect(nativeDispatchErrorFromSignal({ kind: 'failure', message: 'boom' }, 'state.load', []).kind).toBe('native_failure'); + expect(nativeDispatchErrorFromSignal({ kind: 'timeout', message: 'timeout', timeoutMs: 1000 }, 'state.load', []).kind).toBe('native_timeout'); + expect(fallbackDispatchErrorFromSignal({ kind: 'failure', message: 'spawn' }, 'state', ['load']).kind).toBe('fallback_failure'); + }); }); diff --git a/sdk/src/query/query-error-taxonomy.ts b/sdk/src/query/query-error-taxonomy.ts index c43e440e1..67543728e 100644 --- a/sdk/src/query/query-error-taxonomy.ts +++ b/sdk/src/query/query-error-taxonomy.ts @@ -1,6 +1,6 @@ import type { QueryDispatchError } from './query-dispatch-contract.js'; +import type { QueryFailureSignal } from '../query-failure-classification.js'; import { fallbackErrorDetails, nativeErrorDetails, unknownCommandDetails } from './query-error-details-schema.js'; - export function unknownCommandError(input: { message: string; normalized: string; @@ -96,3 +96,22 @@ export function internalError(input: { details: input.details, }; } + +export function nativeDispatchErrorFromSignal( + signal: QueryFailureSignal, + command: string, + args: string[], +): QueryDispatchError { + if (signal.kind === 'timeout') { + return nativeTimeoutError({ message: signal.message, command, args, timeoutMs: signal.timeoutMs }); + } + return nativeFailureError({ message: signal.message, command, args }); +} + +export function fallbackDispatchErrorFromSignal( + signal: QueryFailureSignal, + command: string, + args: string[], +): QueryDispatchError { + return fallbackFailureError({ message: signal.message, command, args, backend: 'cjs' }); +}