73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import { RetryStrategy } from '../src/index.js';
|
|
|
|
describe('RetryStrategy', () => {
|
|
it('uses exponential backoff for recoverable errors', async () => {
|
|
const strategy = new RetryStrategy({
|
|
maxAttempts: 4,
|
|
baseDelayMs: 100,
|
|
classifyError: async () => 'recoverable',
|
|
});
|
|
|
|
const decision = await strategy.shouldRetry(new Error('boom'), {
|
|
id: 'job-1',
|
|
status: 'active',
|
|
data: {},
|
|
currentPhase: 'run',
|
|
phases: [],
|
|
phaseResults: {},
|
|
progress: 0,
|
|
progressMessage: null,
|
|
error: null,
|
|
retryCount: 1,
|
|
maxAttempts: 4,
|
|
webhookUrl: null,
|
|
webhookSent: false,
|
|
createdAt: new Date().toISOString(),
|
|
startedAt: null,
|
|
completedAt: null,
|
|
updatedAt: new Date().toISOString(),
|
|
scheduledAt: null,
|
|
cancelledAt: null,
|
|
});
|
|
|
|
expect(decision.retry).toBe(true);
|
|
expect(decision.delayMs).toBe(200);
|
|
expect(decision.disposition).toBe('recoverable');
|
|
});
|
|
|
|
it('does not retry fatal errors', async () => {
|
|
const strategy = new RetryStrategy({
|
|
maxAttempts: 4,
|
|
classifyError: async () => 'fatal',
|
|
});
|
|
|
|
const decision = await strategy.shouldRetry(new Error('fatal'), {
|
|
id: 'job-1',
|
|
status: 'active',
|
|
data: {},
|
|
currentPhase: 'run',
|
|
phases: [],
|
|
phaseResults: {},
|
|
progress: 0,
|
|
progressMessage: null,
|
|
error: null,
|
|
retryCount: 0,
|
|
maxAttempts: 4,
|
|
webhookUrl: null,
|
|
webhookSent: false,
|
|
createdAt: new Date().toISOString(),
|
|
startedAt: null,
|
|
completedAt: null,
|
|
updatedAt: new Date().toISOString(),
|
|
scheduledAt: null,
|
|
cancelledAt: null,
|
|
});
|
|
|
|
expect(decision).toEqual({
|
|
retry: false,
|
|
delayMs: 0,
|
|
disposition: 'fatal',
|
|
});
|
|
});
|
|
});
|