refactor: default typed failure classification across query errors
This commit is contained in:
@@ -34,7 +34,9 @@ export function createGSDToolsRuntime(opts: {
|
||||
timeoutMs: opts.timeoutMs,
|
||||
workstream: opts.workstream,
|
||||
createToolsError: (message, command, args, exitCode, stderr, classification) =>
|
||||
new GSDToolsError(message, command, args, exitCode, stderr, classification ? { classification } : undefined),
|
||||
new GSDToolsError(message, command, args, exitCode, stderr, {
|
||||
classification: classification ?? { kind: 'failure' },
|
||||
}),
|
||||
});
|
||||
|
||||
const nativeDirectAdapter = new QueryNativeDirectAdapter({
|
||||
|
||||
@@ -14,8 +14,8 @@ describe('query tools error mapper', () => {
|
||||
expect(err.classification).toEqual({ kind: 'timeout', timeoutMs: 1234 });
|
||||
});
|
||||
|
||||
it('does not attach timeout classification for non-timeout failures', () => {
|
||||
it('attaches failure classification for non-timeout failures', () => {
|
||||
const err = toGSDToolsError('state', ['load'], new Error('boom'));
|
||||
expect(err.classification).toBeUndefined();
|
||||
expect(err.classification).toEqual({ kind: 'failure' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { GSDError, exitCodeFor } from './errors.js';
|
||||
import { GSDToolsError } from './gsd-tools-error.js';
|
||||
import { isTimeoutMessage, errorMessage, parseTimeoutMs } from './query-failure-classification.js';
|
||||
import { errorMessage, toFailureSignal } from './query-failure-classification.js';
|
||||
|
||||
/**
|
||||
* Module owning projection of internal errors to GSDToolsError contract.
|
||||
@@ -18,6 +18,11 @@ export function toGSDToolsError(command: string, args: string[], err: unknown):
|
||||
}
|
||||
|
||||
const msg = errorMessage(err);
|
||||
const signal = toFailureSignal(err);
|
||||
const classification = signal.kind === 'timeout'
|
||||
? { kind: 'timeout' as const, timeoutMs: signal.timeoutMs }
|
||||
: { kind: 'failure' as const };
|
||||
|
||||
return new GSDToolsError(
|
||||
msg,
|
||||
command,
|
||||
@@ -25,14 +30,7 @@ export function toGSDToolsError(command: string, args: string[], err: unknown):
|
||||
1,
|
||||
'',
|
||||
err instanceof Error
|
||||
? {
|
||||
cause: err,
|
||||
...(isTimeoutMessage(msg)
|
||||
? { classification: { kind: 'timeout' as const, timeoutMs: parseTimeoutMs(msg) } }
|
||||
: undefined),
|
||||
}
|
||||
: (isTimeoutMessage(msg)
|
||||
? { classification: { kind: 'timeout' as const, timeoutMs: parseTimeoutMs(msg) } }
|
||||
: undefined),
|
||||
? { cause: err, classification }
|
||||
: { classification },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,17 @@ describe('query dispatch error mapper', () => {
|
||||
expect(err.details).toMatchObject({ timeout_ms: 1234 });
|
||||
});
|
||||
|
||||
it('maps typed failure classification from GSDToolsError', () => {
|
||||
const err = mapNativeDispatchError(
|
||||
new GSDToolsError('boom', 'state', ['load'], 1, '', {
|
||||
classification: { kind: 'failure' },
|
||||
}),
|
||||
'state.load',
|
||||
[],
|
||||
);
|
||||
expect(err.kind).toBe('native_failure');
|
||||
});
|
||||
|
||||
it('maps fallback errors', () => {
|
||||
const err = mapFallbackDispatchError(new Error('spawn ENOENT'), 'state', ['load']);
|
||||
expect(err.kind).toBe('fallback_failure');
|
||||
|
||||
Reference in New Issue
Block a user