refactor: centralize dispatch error projection from failure signals

This commit is contained in:
Tom Boucher
2026-05-04 19:58:20 -04:00
parent 5cfd874058
commit 7298a76b20
3 changed files with 31 additions and 9 deletions

View File

@@ -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);
}

View File

@@ -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');
});
});

View File

@@ -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' });
}