tool-call-retry 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -0
- package/dist/__tests__/backoff.test.d.ts +2 -0
- package/dist/__tests__/backoff.test.d.ts.map +1 -0
- package/dist/__tests__/backoff.test.js +117 -0
- package/dist/__tests__/backoff.test.js.map +1 -0
- package/dist/__tests__/circuit-breaker.test.d.ts +2 -0
- package/dist/__tests__/circuit-breaker.test.d.ts.map +1 -0
- package/dist/__tests__/circuit-breaker.test.js +129 -0
- package/dist/__tests__/circuit-breaker.test.js.map +1 -0
- package/dist/__tests__/classify.test.d.ts +2 -0
- package/dist/__tests__/classify.test.d.ts.map +1 -0
- package/dist/__tests__/classify.test.js +139 -0
- package/dist/__tests__/classify.test.js.map +1 -0
- package/dist/__tests__/retry.test.d.ts +2 -0
- package/dist/__tests__/retry.test.d.ts.map +1 -0
- package/dist/__tests__/retry.test.js +277 -0
- package/dist/__tests__/retry.test.js.map +1 -0
- package/dist/backoff.d.ts +3 -0
- package/dist/backoff.d.ts.map +1 -0
- package/dist/backoff.js +37 -0
- package/dist/backoff.js.map +1 -0
- package/dist/circuit-breaker.d.ts +10 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +100 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/classify.d.ts +3 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +112 -0
- package/dist/classify.js.map +1 -0
- package/dist/format-error.d.ts +6 -0
- package/dist/format-error.d.ts.map +1 -0
- package/dist/format-error.js +73 -0
- package/dist/format-error.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/retry.d.ts +7 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +127 -0
- package/dist/retry.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# tool-call-retry
|
|
2
|
+
|
|
3
|
+
AI-specific retry wrapper with circuit breaker for LLM tool calls. Zero external runtime dependencies.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install tool-call-retry
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start — `withRetry`
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { withRetry } from 'tool-call-retry';
|
|
15
|
+
|
|
16
|
+
const result = await withRetry(
|
|
17
|
+
() => callMyTool(args),
|
|
18
|
+
{
|
|
19
|
+
maxRetries: 3,
|
|
20
|
+
policy: { strategy: 'exponential', initialDelayMs: 1000, jitter: 'full' },
|
|
21
|
+
onPermanentFailure: 'return-error', // returns LLMFormattedError instead of throwing
|
|
22
|
+
toolName: 'search',
|
|
23
|
+
hooks: {
|
|
24
|
+
onRetry: ({ attempt, delayMs, classification }) =>
|
|
25
|
+
console.log(`Attempt ${attempt} failed (${classification.code}), retrying in ${delayMs}ms`),
|
|
26
|
+
onSuccess: ({ attempts, totalMs }) =>
|
|
27
|
+
console.log(`Succeeded after ${attempts} attempt(s) in ${totalMs}ms`),
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (result && typeof result === 'object' && result.error === true) {
|
|
33
|
+
// LLMFormattedError — safe to pass back to the LLM
|
|
34
|
+
console.log(result.message, result.suggestion);
|
|
35
|
+
} else {
|
|
36
|
+
// actual result
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## `wrapTools`
|
|
41
|
+
|
|
42
|
+
Wraps an entire tools map so every call goes through retry:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { wrapTools } from 'tool-call-retry';
|
|
46
|
+
|
|
47
|
+
const tools = {
|
|
48
|
+
search: (args) => fetch(...),
|
|
49
|
+
calculate: (args) => compute(...),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const retryingTools = wrapTools(tools, {
|
|
53
|
+
maxRetries: 3,
|
|
54
|
+
onPermanentFailure: 'return-error',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// retryingTools.search / retryingTools.calculate are now retry-wrapped
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Circuit breaker
|
|
61
|
+
|
|
62
|
+
The circuit breaker is enabled by default (threshold: 5 failures in 60 s, resets after 30 s).
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { withRetry } from 'tool-call-retry';
|
|
66
|
+
|
|
67
|
+
await withRetry(() => callTool(), {
|
|
68
|
+
circuitBreaker: {
|
|
69
|
+
failureThreshold: 3,
|
|
70
|
+
rollingWindowMs: 30000,
|
|
71
|
+
resetTimeoutMs: 15000,
|
|
72
|
+
successThreshold: 1,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Disable entirely:
|
|
77
|
+
await withRetry(() => callTool(), { circuitBreaker: false });
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
You can also create and reuse a circuit breaker instance:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createCircuitBreaker } from 'tool-call-retry';
|
|
84
|
+
|
|
85
|
+
const cb = createCircuitBreaker({ failureThreshold: 5 });
|
|
86
|
+
cb.on('open', () => console.warn('Circuit opened'));
|
|
87
|
+
cb.on('close', () => console.info('Circuit closed'));
|
|
88
|
+
|
|
89
|
+
console.log(cb.state); // 'closed' | 'open' | 'half-open'
|
|
90
|
+
console.log(cb.isCallPermitted); // boolean
|
|
91
|
+
cb.recordSuccess();
|
|
92
|
+
cb.recordFailure();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Error classification
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { classifyError } from 'tool-call-retry';
|
|
99
|
+
|
|
100
|
+
const c = classifyError(error);
|
|
101
|
+
// c.category: 'retriable' | 'non-retriable' | 'rate-limited' | 'timeout' | 'unknown'
|
|
102
|
+
// c.code: e.g. 'RATE_LIMITED', 'SERVER_ERROR', 'CLIENT_ERROR', 'NETWORK_ERROR', 'TIMEOUT', ...
|
|
103
|
+
// c.retryAfterMs: number | undefined (populated for 429 responses)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Custom classifier:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
await withRetry(() => callTool(), {
|
|
110
|
+
classifyError: (err) => {
|
|
111
|
+
if (isMyCustomError(err)) return { category: 'retriable', code: 'MY_ERROR', message: '...' };
|
|
112
|
+
return null; // fall through to default classification
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Retry policy options
|
|
118
|
+
|
|
119
|
+
| Option | Default | Description |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `maxRetries` | `3` | Maximum retry attempts |
|
|
122
|
+
| `strategy` | `'exponential'` | `'exponential'` \| `'linear'` \| `'fixed'` |
|
|
123
|
+
| `initialDelayMs` | `1000` | Base delay in ms |
|
|
124
|
+
| `maxDelayMs` | `30000` | Delay cap in ms |
|
|
125
|
+
| `multiplier` | `2` | Exponent base (exponential only) |
|
|
126
|
+
| `jitter` | `'full'` | `'full'` \| `'equal'` \| `'decorrelated'` \| `'none'` |
|
|
127
|
+
| `maxTotalTimeMs` | `60000` | Total time budget before giving up |
|
|
128
|
+
|
|
129
|
+
## LLMFormattedError shape
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
{
|
|
133
|
+
error: true,
|
|
134
|
+
code: string, // e.g. 'RATE_LIMITED', 'SERVICE_UNAVAILABLE'
|
|
135
|
+
message: string, // sanitized (no stack traces, tokens, passwords)
|
|
136
|
+
retriable: boolean,
|
|
137
|
+
suggestion: string, // human-readable next-step hint
|
|
138
|
+
tool?: string, // tool name if provided
|
|
139
|
+
attemptsMade?: number,
|
|
140
|
+
}
|
|
141
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/backoff.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const backoff_js_1 = require("../backoff.js");
|
|
5
|
+
function makePolicy(overrides) {
|
|
6
|
+
return {
|
|
7
|
+
maxRetries: 3,
|
|
8
|
+
strategy: 'exponential',
|
|
9
|
+
initialDelayMs: 1000,
|
|
10
|
+
maxDelayMs: 30000,
|
|
11
|
+
multiplier: 2,
|
|
12
|
+
jitter: 'none',
|
|
13
|
+
maxTotalTimeMs: 60000,
|
|
14
|
+
...overrides,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
(0, vitest_1.describe)('computeDelay', () => {
|
|
18
|
+
(0, vitest_1.describe)('exponential strategy', () => {
|
|
19
|
+
(0, vitest_1.it)('returns initialDelayMs on attempt 1', () => {
|
|
20
|
+
const policy = makePolicy();
|
|
21
|
+
const delay = (0, backoff_js_1.computeDelay)(1, policy, policy.initialDelayMs);
|
|
22
|
+
(0, vitest_1.expect)(delay).toBe(1000);
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)('doubles on attempt 2', () => {
|
|
25
|
+
const policy = makePolicy();
|
|
26
|
+
const delay = (0, backoff_js_1.computeDelay)(2, policy, 1000);
|
|
27
|
+
(0, vitest_1.expect)(delay).toBe(2000);
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)('grows to 4x on attempt 3', () => {
|
|
30
|
+
const policy = makePolicy();
|
|
31
|
+
const delay = (0, backoff_js_1.computeDelay)(3, policy, 2000);
|
|
32
|
+
(0, vitest_1.expect)(delay).toBe(4000);
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)('is capped at maxDelayMs', () => {
|
|
35
|
+
const policy = makePolicy({ maxDelayMs: 3000 });
|
|
36
|
+
const delay = (0, backoff_js_1.computeDelay)(5, policy, 3000);
|
|
37
|
+
(0, vitest_1.expect)(delay).toBe(3000);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
(0, vitest_1.describe)('linear strategy', () => {
|
|
41
|
+
(0, vitest_1.it)('returns 1x initialDelayMs on attempt 1', () => {
|
|
42
|
+
const policy = makePolicy({ strategy: 'linear' });
|
|
43
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, 1000)).toBe(1000);
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)('returns 2x initialDelayMs on attempt 2', () => {
|
|
46
|
+
const policy = makePolicy({ strategy: 'linear' });
|
|
47
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(2, policy, 1000)).toBe(2000);
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.it)('is capped at maxDelayMs', () => {
|
|
50
|
+
const policy = makePolicy({ strategy: 'linear', maxDelayMs: 1500 });
|
|
51
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(3, policy, 1500)).toBe(1500);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
(0, vitest_1.describe)('fixed strategy', () => {
|
|
55
|
+
(0, vitest_1.it)('always returns initialDelayMs', () => {
|
|
56
|
+
const policy = makePolicy({ strategy: 'fixed' });
|
|
57
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, 0)).toBe(1000);
|
|
58
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(5, policy, 5000)).toBe(1000);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.describe)('jitter', () => {
|
|
62
|
+
const rng05 = () => 0.5;
|
|
63
|
+
const rng0 = () => 0;
|
|
64
|
+
const rng1 = () => 0.9999;
|
|
65
|
+
(0, vitest_1.it)('full jitter: result is in [0, baseDelay]', () => {
|
|
66
|
+
const policy = makePolicy({ jitter: 'full', strategy: 'exponential' });
|
|
67
|
+
for (let i = 0; i < 20; i++) {
|
|
68
|
+
const delay = (0, backoff_js_1.computeDelay)(1, policy, 1000);
|
|
69
|
+
(0, vitest_1.expect)(delay).toBeGreaterThanOrEqual(0);
|
|
70
|
+
(0, vitest_1.expect)(delay).toBeLessThanOrEqual(1000);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
(0, vitest_1.it)('full jitter: scales with rng value', () => {
|
|
74
|
+
const policy = makePolicy({ jitter: 'full', strategy: 'exponential' });
|
|
75
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, 1000, rng05)).toBe(Math.round(0.5 * 1000));
|
|
76
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, 1000, rng0)).toBe(0);
|
|
77
|
+
});
|
|
78
|
+
(0, vitest_1.it)('equal jitter: result is in [baseDelay/2, baseDelay]', () => {
|
|
79
|
+
const policy = makePolicy({ jitter: 'equal', strategy: 'exponential' });
|
|
80
|
+
for (let i = 0; i < 20; i++) {
|
|
81
|
+
const delay = (0, backoff_js_1.computeDelay)(1, policy, 1000);
|
|
82
|
+
(0, vitest_1.expect)(delay).toBeGreaterThanOrEqual(500);
|
|
83
|
+
(0, vitest_1.expect)(delay).toBeLessThanOrEqual(1000);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
(0, vitest_1.it)('equal jitter: lower bound is baseDelay/2 when rng=0', () => {
|
|
87
|
+
const policy = makePolicy({ jitter: 'equal', strategy: 'exponential' });
|
|
88
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, 1000, rng0)).toBe(500);
|
|
89
|
+
});
|
|
90
|
+
(0, vitest_1.it)('none jitter: returns exact baseDelay', () => {
|
|
91
|
+
const policy = makePolicy({ jitter: 'none' });
|
|
92
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(2, policy, 1000)).toBe(2000);
|
|
93
|
+
});
|
|
94
|
+
(0, vitest_1.it)('decorrelated: bounded by maxDelayMs', () => {
|
|
95
|
+
const policy = makePolicy({ jitter: 'decorrelated', strategy: 'exponential', maxDelayMs: 5000 });
|
|
96
|
+
for (let i = 0; i < 20; i++) {
|
|
97
|
+
const delay = (0, backoff_js_1.computeDelay)(2, policy, 1000);
|
|
98
|
+
(0, vitest_1.expect)(delay).toBeLessThanOrEqual(5000);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
(0, vitest_1.it)('decorrelated: uses rng correctly', () => {
|
|
102
|
+
const policy = makePolicy({ jitter: 'decorrelated', strategy: 'exponential', maxDelayMs: 30000 });
|
|
103
|
+
// decorrelated = rng * (prev*3 - initial) + initial, prev=1000
|
|
104
|
+
// = rng * (3000 - 1000) + 1000 = rng * 2000 + 1000
|
|
105
|
+
const prev = 1000;
|
|
106
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, prev, rng0)).toBe(Math.round(0 * 2000 + 1000));
|
|
107
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(1, policy, prev, rng1)).toBe(Math.round(0.9999 * 2000 + 1000));
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
(0, vitest_1.describe)('maxDelayMs enforcement', () => {
|
|
111
|
+
(0, vitest_1.it)('caps exponential at maxDelayMs with none jitter', () => {
|
|
112
|
+
const policy = makePolicy({ maxDelayMs: 500, strategy: 'exponential', jitter: 'none' });
|
|
113
|
+
(0, vitest_1.expect)((0, backoff_js_1.computeDelay)(10, policy, 500)).toBe(500);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=backoff.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.test.js","sourceRoot":"","sources":["../../src/__tests__/backoff.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/circuit-breaker.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const circuit_breaker_js_1 = require("../circuit-breaker.js");
|
|
5
|
+
(0, vitest_1.describe)('createCircuitBreaker', () => {
|
|
6
|
+
(0, vitest_1.beforeEach)(() => {
|
|
7
|
+
vitest_1.vi.useFakeTimers();
|
|
8
|
+
});
|
|
9
|
+
(0, vitest_1.afterEach)(() => {
|
|
10
|
+
vitest_1.vi.useRealTimers();
|
|
11
|
+
});
|
|
12
|
+
(0, vitest_1.it)('starts in closed state', () => {
|
|
13
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 3 });
|
|
14
|
+
(0, vitest_1.expect)(cb.state).toBe('closed');
|
|
15
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
(0, vitest_1.it)('remains closed below failure threshold', () => {
|
|
18
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 3 });
|
|
19
|
+
cb.recordFailure();
|
|
20
|
+
cb.recordFailure();
|
|
21
|
+
(0, vitest_1.expect)(cb.state).toBe('closed');
|
|
22
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
(0, vitest_1.it)('opens after reaching failure threshold', () => {
|
|
25
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 3 });
|
|
26
|
+
cb.recordFailure();
|
|
27
|
+
cb.recordFailure();
|
|
28
|
+
cb.recordFailure();
|
|
29
|
+
(0, vitest_1.expect)(cb.state).toBe('open');
|
|
30
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)('emits "open" event when transitioning to open', () => {
|
|
33
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2 });
|
|
34
|
+
const handler = vitest_1.vi.fn();
|
|
35
|
+
cb.on('open', handler);
|
|
36
|
+
cb.recordFailure();
|
|
37
|
+
cb.recordFailure();
|
|
38
|
+
(0, vitest_1.expect)(handler).toHaveBeenCalledTimes(1);
|
|
39
|
+
});
|
|
40
|
+
(0, vitest_1.it)('transitions to half-open after resetTimeoutMs', () => {
|
|
41
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2, resetTimeoutMs: 5000 });
|
|
42
|
+
cb.recordFailure();
|
|
43
|
+
cb.recordFailure();
|
|
44
|
+
(0, vitest_1.expect)(cb.state).toBe('open');
|
|
45
|
+
vitest_1.vi.advanceTimersByTime(5000);
|
|
46
|
+
(0, vitest_1.expect)(cb.state).toBe('half-open');
|
|
47
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.it)('emits "half-open" event on transition', () => {
|
|
50
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2, resetTimeoutMs: 5000 });
|
|
51
|
+
const handler = vitest_1.vi.fn();
|
|
52
|
+
cb.on('half-open', handler);
|
|
53
|
+
cb.recordFailure();
|
|
54
|
+
cb.recordFailure();
|
|
55
|
+
vitest_1.vi.advanceTimersByTime(5000);
|
|
56
|
+
// Accessing state triggers the checkHalfOpen transition
|
|
57
|
+
(0, vitest_1.expect)(cb.state).toBe('half-open');
|
|
58
|
+
(0, vitest_1.expect)(handler).toHaveBeenCalledTimes(1);
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.it)('closes after success in half-open state', () => {
|
|
61
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2, resetTimeoutMs: 5000, successThreshold: 1 });
|
|
62
|
+
cb.recordFailure();
|
|
63
|
+
cb.recordFailure();
|
|
64
|
+
vitest_1.vi.advanceTimersByTime(5000);
|
|
65
|
+
(0, vitest_1.expect)(cb.state).toBe('half-open');
|
|
66
|
+
cb.recordSuccess();
|
|
67
|
+
(0, vitest_1.expect)(cb.state).toBe('closed');
|
|
68
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
(0, vitest_1.it)('emits "close" event when closing from half-open', () => {
|
|
71
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2, resetTimeoutMs: 5000 });
|
|
72
|
+
const handler = vitest_1.vi.fn();
|
|
73
|
+
cb.on('close', handler);
|
|
74
|
+
cb.recordFailure();
|
|
75
|
+
cb.recordFailure();
|
|
76
|
+
vitest_1.vi.advanceTimersByTime(5000);
|
|
77
|
+
void cb.state; // trigger half-open
|
|
78
|
+
cb.recordSuccess();
|
|
79
|
+
(0, vitest_1.expect)(handler).toHaveBeenCalledTimes(1);
|
|
80
|
+
});
|
|
81
|
+
(0, vitest_1.it)('goes back to open on failure in half-open state', () => {
|
|
82
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2, resetTimeoutMs: 5000 });
|
|
83
|
+
cb.recordFailure();
|
|
84
|
+
cb.recordFailure();
|
|
85
|
+
vitest_1.vi.advanceTimersByTime(5000);
|
|
86
|
+
(0, vitest_1.expect)(cb.state).toBe('half-open');
|
|
87
|
+
cb.recordFailure();
|
|
88
|
+
(0, vitest_1.expect)(cb.state).toBe('open');
|
|
89
|
+
(0, vitest_1.expect)(cb.isCallPermitted).toBe(false);
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)('resets failure count after closing', () => {
|
|
92
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 3, resetTimeoutMs: 1000 });
|
|
93
|
+
cb.recordFailure();
|
|
94
|
+
cb.recordFailure();
|
|
95
|
+
cb.recordFailure(); // open
|
|
96
|
+
vitest_1.vi.advanceTimersByTime(1000);
|
|
97
|
+
void cb.state; // half-open
|
|
98
|
+
cb.recordSuccess(); // close
|
|
99
|
+
// Should need 3 new failures to open again
|
|
100
|
+
cb.recordFailure();
|
|
101
|
+
cb.recordFailure();
|
|
102
|
+
(0, vitest_1.expect)(cb.state).toBe('closed');
|
|
103
|
+
cb.recordFailure();
|
|
104
|
+
(0, vitest_1.expect)(cb.state).toBe('open');
|
|
105
|
+
});
|
|
106
|
+
(0, vitest_1.it)('removes listener when unsubscribe function is called', () => {
|
|
107
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({ failureThreshold: 2 });
|
|
108
|
+
const handler = vitest_1.vi.fn();
|
|
109
|
+
const unsubscribe = cb.on('open', handler);
|
|
110
|
+
unsubscribe();
|
|
111
|
+
cb.recordFailure();
|
|
112
|
+
cb.recordFailure();
|
|
113
|
+
(0, vitest_1.expect)(handler).not.toHaveBeenCalled();
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.it)('does not count failures outside rolling window', () => {
|
|
116
|
+
const cb = (0, circuit_breaker_js_1.createCircuitBreaker)({
|
|
117
|
+
failureThreshold: 3,
|
|
118
|
+
rollingWindowMs: 5000,
|
|
119
|
+
});
|
|
120
|
+
cb.recordFailure();
|
|
121
|
+
cb.recordFailure();
|
|
122
|
+
// Advance past rolling window
|
|
123
|
+
vitest_1.vi.advanceTimersByTime(6000);
|
|
124
|
+
// This failure is within the window, the previous two are not
|
|
125
|
+
cb.recordFailure();
|
|
126
|
+
(0, vitest_1.expect)(cb.state).toBe('closed');
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=circuit-breaker.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.test.js","sourceRoot":"","sources":["../../src/__tests__/circuit-breaker.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/classify.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const classify_js_1 = require("../classify.js");
|
|
5
|
+
(0, vitest_1.describe)('classifyError', () => {
|
|
6
|
+
(0, vitest_1.it)('classifies HTTP 429 as rate-limited', () => {
|
|
7
|
+
const err = Object.assign(new Error('Too Many Requests'), { status: 429 });
|
|
8
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
9
|
+
(0, vitest_1.expect)(result.category).toBe('rate-limited');
|
|
10
|
+
(0, vitest_1.expect)(result.code).toBe('RATE_LIMITED');
|
|
11
|
+
(0, vitest_1.expect)(result.statusCode).toBe(429);
|
|
12
|
+
});
|
|
13
|
+
(0, vitest_1.it)('extracts retryAfterMs from headers', () => {
|
|
14
|
+
const err = Object.assign(new Error('Rate limited'), {
|
|
15
|
+
status: 429,
|
|
16
|
+
headers: { 'retry-after': '5' },
|
|
17
|
+
});
|
|
18
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
19
|
+
(0, vitest_1.expect)(result.retryAfterMs).toBe(5000);
|
|
20
|
+
});
|
|
21
|
+
(0, vitest_1.it)('extracts retryAfterMs from retryAfter property', () => {
|
|
22
|
+
const err = Object.assign(new Error('Rate limited'), {
|
|
23
|
+
status: 429,
|
|
24
|
+
retryAfter: 10000,
|
|
25
|
+
});
|
|
26
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
27
|
+
(0, vitest_1.expect)(result.retryAfterMs).toBe(10000);
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)('classifies HTTP 404 as non-retriable', () => {
|
|
30
|
+
const err = Object.assign(new Error('Not Found'), { status: 404 });
|
|
31
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
32
|
+
(0, vitest_1.expect)(result.category).toBe('non-retriable');
|
|
33
|
+
(0, vitest_1.expect)(result.code).toBe('CLIENT_ERROR');
|
|
34
|
+
(0, vitest_1.expect)(result.statusCode).toBe(404);
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.it)('classifies HTTP 401 as non-retriable', () => {
|
|
37
|
+
const err = Object.assign(new Error('Unauthorized'), { status: 401 });
|
|
38
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
39
|
+
(0, vitest_1.expect)(result.category).toBe('non-retriable');
|
|
40
|
+
(0, vitest_1.expect)(result.statusCode).toBe(401);
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)('classifies HTTP 422 as non-retriable', () => {
|
|
43
|
+
const err = Object.assign(new Error('Unprocessable'), { status: 422 });
|
|
44
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
45
|
+
(0, vitest_1.expect)(result.category).toBe('non-retriable');
|
|
46
|
+
(0, vitest_1.expect)(result.statusCode).toBe(422);
|
|
47
|
+
});
|
|
48
|
+
(0, vitest_1.it)('classifies HTTP 503 as retriable', () => {
|
|
49
|
+
const err = Object.assign(new Error('Service Unavailable'), { status: 503 });
|
|
50
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
51
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
52
|
+
(0, vitest_1.expect)(result.code).toBe('SERVER_ERROR');
|
|
53
|
+
(0, vitest_1.expect)(result.statusCode).toBe(503);
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.it)('classifies HTTP 500 as retriable', () => {
|
|
56
|
+
const err = Object.assign(new Error('Internal Server Error'), { status: 500 });
|
|
57
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
58
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.it)('classifies HTTP 502 as retriable', () => {
|
|
61
|
+
const err = Object.assign(new Error('Bad Gateway'), { statusCode: 502 });
|
|
62
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
63
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
64
|
+
});
|
|
65
|
+
(0, vitest_1.it)('classifies ECONNREFUSED as retriable', () => {
|
|
66
|
+
const err = Object.assign(new Error('connection refused'), { code: 'ECONNREFUSED' });
|
|
67
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
68
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
69
|
+
(0, vitest_1.expect)(result.code).toBe('NETWORK_ERROR');
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)('classifies ECONNRESET as retriable', () => {
|
|
72
|
+
const err = Object.assign(new Error('socket hang up'), { code: 'ECONNRESET' });
|
|
73
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
74
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
75
|
+
(0, vitest_1.expect)(result.code).toBe('NETWORK_ERROR');
|
|
76
|
+
});
|
|
77
|
+
(0, vitest_1.it)('classifies EPIPE as retriable', () => {
|
|
78
|
+
const err = Object.assign(new Error('broken pipe'), { code: 'EPIPE' });
|
|
79
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
80
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
81
|
+
(0, vitest_1.expect)(result.code).toBe('NETWORK_ERROR');
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.it)('classifies ETIMEDOUT as timeout', () => {
|
|
84
|
+
const err = Object.assign(new Error('timed out'), { code: 'ETIMEDOUT' });
|
|
85
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
86
|
+
(0, vitest_1.expect)(result.category).toBe('timeout');
|
|
87
|
+
(0, vitest_1.expect)(result.code).toBe('TIMEOUT');
|
|
88
|
+
});
|
|
89
|
+
(0, vitest_1.it)('classifies ENOTFOUND as retriable DNS error', () => {
|
|
90
|
+
const err = Object.assign(new Error('getaddrinfo ENOTFOUND'), { code: 'ENOTFOUND' });
|
|
91
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
92
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
93
|
+
(0, vitest_1.expect)(result.code).toBe('DNS_ERROR');
|
|
94
|
+
});
|
|
95
|
+
(0, vitest_1.it)('classifies EAI_AGAIN as retriable DNS error', () => {
|
|
96
|
+
const err = Object.assign(new Error('DNS lookup failed'), { code: 'EAI_AGAIN' });
|
|
97
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
98
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
99
|
+
(0, vitest_1.expect)(result.code).toBe('DNS_ERROR');
|
|
100
|
+
});
|
|
101
|
+
(0, vitest_1.it)('classifies message containing "timeout" as timeout', () => {
|
|
102
|
+
const err = new Error('Request timeout exceeded');
|
|
103
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
104
|
+
(0, vitest_1.expect)(result.category).toBe('timeout');
|
|
105
|
+
(0, vitest_1.expect)(result.code).toBe('TIMEOUT');
|
|
106
|
+
});
|
|
107
|
+
(0, vitest_1.it)('classifies AbortError as non-retriable', () => {
|
|
108
|
+
const err = new Error('Aborted');
|
|
109
|
+
err.name = 'AbortError';
|
|
110
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
111
|
+
(0, vitest_1.expect)(result.category).toBe('non-retriable');
|
|
112
|
+
(0, vitest_1.expect)(result.code).toBe('ABORTED');
|
|
113
|
+
});
|
|
114
|
+
(0, vitest_1.it)('falls back to unknown for unrecognized errors', () => {
|
|
115
|
+
const err = new Error('Something weird happened');
|
|
116
|
+
const result = (0, classify_js_1.classifyError)(err);
|
|
117
|
+
(0, vitest_1.expect)(result.category).toBe('unknown');
|
|
118
|
+
(0, vitest_1.expect)(result.code).toBe('UNKNOWN_ERROR');
|
|
119
|
+
});
|
|
120
|
+
(0, vitest_1.it)('uses custom classifier when provided and returns non-null', () => {
|
|
121
|
+
const err = new Error('custom error');
|
|
122
|
+
const custom = () => ({
|
|
123
|
+
category: 'retriable',
|
|
124
|
+
code: 'CUSTOM',
|
|
125
|
+
message: 'custom',
|
|
126
|
+
});
|
|
127
|
+
const result = (0, classify_js_1.classifyError)(err, custom);
|
|
128
|
+
(0, vitest_1.expect)(result.code).toBe('CUSTOM');
|
|
129
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.it)('falls through to default classification when custom classifier returns null', () => {
|
|
132
|
+
const err = Object.assign(new Error('Service Unavailable'), { status: 503 });
|
|
133
|
+
const custom = () => null;
|
|
134
|
+
const result = (0, classify_js_1.classifyError)(err, custom);
|
|
135
|
+
(0, vitest_1.expect)(result.category).toBe('retriable');
|
|
136
|
+
(0, vitest_1.expect)(result.code).toBe('SERVER_ERROR');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=classify.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.test.js","sourceRoot":"","sources":["../../src/__tests__/classify.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/retry.test.ts"],"names":[],"mappings":""}
|