refactor(query): deepen dispatch policy seam with structured result contract (#3066)
* refactor(query): deepen dispatch policy seam with structured result contract Closes #3065. - unify query dispatch outcome as typed success/failure union - include error kind/details + final exit_code in failure path - align native and fallback paths under one dispatch policy seam - make CLI query path consume seam result (thin adapter) - add ADR + context term for Dispatch Policy Module * refactor(query): strengthen dispatch seam with shared error mapper and typed details - add query-dispatch-error-mapper module shared by native/fallback paths - remove ad-hoc inline mapping in dispatch/fallback executors - lock error-details schema in mapper + dispatch tests - document structured dispatch contract in QUERY-HANDLERS.md * fix(query): return structured fallback failure when path resolution throws - guard resolveGsdToolsPath in cjs dispatch path - map thrown resolution errors to fallback_failure result - add regression test for structured failure contract
This commit is contained in:
42
sdk/src/query/query-dispatch-error-mapper.test.ts
Normal file
42
sdk/src/query/query-dispatch-error-mapper.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
mapNativeDispatchError,
|
||||
mapFallbackDispatchError,
|
||||
toDispatchFailure,
|
||||
} from './query-dispatch-error-mapper.js';
|
||||
|
||||
describe('query dispatch error mapper', () => {
|
||||
it('maps native timeout errors', () => {
|
||||
const err = mapNativeDispatchError(
|
||||
new Error('gsd-tools timed out after 30000ms: state load'),
|
||||
'state.load',
|
||||
[],
|
||||
);
|
||||
expect(err.kind).toBe('native_timeout');
|
||||
expect(err.code).toBe(1);
|
||||
expect(err.details).toMatchObject({ command: 'state.load', args: [], timeout_ms: 30000 });
|
||||
});
|
||||
|
||||
it('maps native non-timeout errors', () => {
|
||||
const err = mapNativeDispatchError(new Error('boom'), 'state.json', []);
|
||||
expect(err.kind).toBe('native_failure');
|
||||
expect(err.code).toBe(1);
|
||||
expect(err.details).toMatchObject({ command: 'state.json', args: [] });
|
||||
});
|
||||
|
||||
it('maps fallback errors', () => {
|
||||
const err = mapFallbackDispatchError(new Error('spawn ENOENT'), 'state', ['load']);
|
||||
expect(err.kind).toBe('fallback_failure');
|
||||
expect(err.code).toBe(1);
|
||||
expect(err.details).toMatchObject({ command: 'state', args: ['load'], backend: 'cjs' });
|
||||
});
|
||||
|
||||
it('builds failure result union', () => {
|
||||
const out = toDispatchFailure({ kind: 'internal_error', code: 1, message: 'Error: x' }, ['warn']);
|
||||
expect(out.ok).toBe(false);
|
||||
if (out.ok) throw new Error('expected failure');
|
||||
expect(out.exit_code).toBe(1);
|
||||
expect(out.stderr).toEqual(['warn']);
|
||||
expect(out.error.kind).toBe('internal_error');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user