File size: 2,763 Bytes
dcedb25 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | import { describe, it, expect } from 'vitest';
import { sanitizeProviderErrorMessage, summarizeAttemptError } from '../../lib/error-redaction.js';
describe('sanitizeProviderErrorMessage', () => {
it('redacts Bearer tokens', () => {
expect(sanitizeProviderErrorMessage('auth failed: Bearer abc.def-123')).toBe(
'auth failed: Bearer [redacted]',
);
});
it('redacts labeled secrets in plain form', () => {
expect(sanitizeProviderErrorMessage('api_key=supersecretvalue rejected')).toBe(
'api_key=[redacted] rejected',
);
});
it('redacts JSON-quoted secret labels', () => {
const out = sanitizeProviderErrorMessage('upstream said {"api_key": "supersecretvalue123"}');
expect(out).not.toContain('supersecretvalue123');
expect(out).toContain('"api_key": "[redacted]');
});
it('redacts bare high-entropy tokens with no known prefix', () => {
const out = sanitizeProviderErrorMessage('key co-A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8 was rejected');
expect(out).not.toContain('A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8');
expect(out).toContain('[redacted-token]');
});
it('redacts URLs including key-bearing query strings', () => {
const out = sanitizeProviderErrorMessage('GET https://api.example.com/v1?key=sk-abc123 failed');
expect(out).not.toContain('api.example.com');
expect(out).toContain('[redacted-url]');
});
it('leaves ordinary provider prose and model ids intact', () => {
const msg = 'model llama-3.3-70b-versatile is over capacity, retry after 30s (HTTP 429)';
expect(sanitizeProviderErrorMessage(msg)).toBe(msg);
});
it('caps message length', () => {
const out = sanitizeProviderErrorMessage('x '.repeat(400));
expect(out.length).toBeLessThanOrEqual(240);
});
});
// The short per-attempt error summary stored in request_attempts.error_summary:
// same redactions as sanitizeProviderErrorMessage, tighter cap (200 chars).
describe('summarizeAttemptError', () => {
it('applies the same secret redactions', () => {
const out = summarizeAttemptError('401 rejected: Bearer sk-abc.def-12345 for key gsk_A1b2C3d4E5f6G7h8');
expect(out).not.toContain('sk-abc.def-12345');
expect(out).not.toContain('gsk_A1b2C3d4E5f6G7h8');
expect(out).toContain('Bearer [redacted]');
});
it('caps the summary at 200 characters with an ellipsis', () => {
const out = summarizeAttemptError('upstream exploded because ' + 'y '.repeat(300));
expect(out.length).toBeLessThanOrEqual(200);
expect(out.endsWith('...')).toBe(true);
});
it('leaves ordinary provider prose intact', () => {
const msg = '429 Too Many Requests: rate limit reached for llama-3.3-70b, retry in 7m12s';
expect(summarizeAttemptError(msg)).toBe(msg);
});
});
|