fix: back off after Reddit access denials

This commit is contained in:
jjbrunton committed 2026-08-08 22:37:19 +01:00
1 parent e8b730b592
commit 53e9a44a5c
5 files changed
+81 -14

No files matched your search

+18 -1
View File
@@ -490,7 +490,7 @@ describe('RedditApiClient', () => {
expect(result).toEqual([]);
});
it('returns empty array for 403 private subreddit', async () => {
it('returns empty array and explains an initial 403 access denial', async () => {
const error = { isAxiosError: true, response: { status: 403 } };
const mockAxios = { get: vi.fn().mockRejectedValue(error) };
vi.mocked(axios.create).mockReturnValue(mockAxios as any);
@@ -498,6 +498,23 @@ describe('RedditApiClient', () => {
const client2 = new RedditApiClient(getTestConfig(), logger);
const result = await client2.getNewPosts('private');
expect(result).toEqual([]);
expect(logger.logs).toContainEqual(expect.objectContaining({
level: 'warn', message: expect.stringContaining('HTTP 403'),
}));
});
it('treats consecutive 403 listing responses as a temporary Reddit block', async () => {
const error = { isAxiosError: true, response: { status: 403 } };
const mockAxios = { get: vi.fn().mockRejectedValue(error) };
vi.mocked(axios.create).mockReturnValue(mockAxios as unknown as AxiosInstance);
const scheduler: RedditRequestScheduler = { schedule: async (request) => await request(), extendCooldown: vi.fn() };
const client2 = new RedditApiClient(getTestConfig(), logger, scheduler);
await expect(client2.getNewPosts('first')).resolves.toEqual([]);
await expect(client2.getNewPosts('second')).rejects.toMatchObject({
name: 'RedditRateLimitError', retryAfterMs: 120_000,
});
expect(scheduler.extendCooldown).toHaveBeenCalledWith(120_000);
});
it('throws a compact error with the Reddit rate-limit reset delay on 429', async () => {
+14
View File
@@ -55,4 +55,18 @@ describe('RedditRequestCoordinator', () => {
await second;
expect(sleeps).toEqual([16_000]);
});
it('paces a queued request after a failed attempt without an explicit cooldown', async () => {
let now = 0;
const sleeps: number[] = [];
const coordinator = new RedditRequestCoordinator(6_500, {
now: () => now,
sleep: async (ms) => { sleeps.push(ms); now += ms; },
});
await expect(coordinator.schedule(async () => { throw new Error('403'); })).rejects.toThrow('403');
await coordinator.schedule(async () => undefined);
expect(sleeps).toEqual([6_500]);
});
});