Skip to content

Commit 5a70057

Browse files
authored
fix(SequentialHandler): downlevel ECONNRESET errors (#8785)
1 parent 0bcc18a commit 5a70057

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

packages/rest/src/lib/handlers/SequentialHandler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { DiscordAPIError, type DiscordErrorData, type OAuthErrorData } from '../
88
import { HTTPError } from '../errors/HTTPError.js';
99
import { RateLimitError } from '../errors/RateLimitError.js';
1010
import { RESTEvents } from '../utils/constants.js';
11-
import { hasSublimit, parseHeader, parseResponse } from '../utils/utils.js';
11+
import { hasSublimit, parseHeader, parseResponse, shouldRetry } from '../utils/utils.js';
1212
import type { IHandler } from './IHandler.js';
1313

1414
/**
@@ -307,8 +307,9 @@ export class SequentialHandler implements IHandler {
307307
try {
308308
res = await request(url, { ...options, signal: controller.signal });
309309
} catch (error: unknown) {
310-
// Retry the specified number of times for possible timed out requests
311-
if (error instanceof Error && error.name === 'AbortError' && retries !== this.manager.options.retries) {
310+
if (!(error instanceof Error)) throw error;
311+
// Retry the specified number of times if needed
312+
if (shouldRetry(error) && retries !== this.manager.options.retries) {
312313
// eslint-disable-next-line no-param-reassign
313314
return await this.runRequest(routeId, url, options, requestData, ++retries);
314315
}

packages/rest/src/lib/utils/utils.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,16 @@ export async function resolveBody(body: RequestInit['body']): Promise<RequestOpt
135135

136136
throw new TypeError(`Unable to resolve body.`);
137137
}
138+
139+
/**
140+
* Check whether an error indicates that a retry can be attempted
141+
*
142+
* @param error - The error thrown by the network request
143+
* @returns Whether the error indicates a retry should be attempted
144+
*/
145+
export function shouldRetry(error: Error | NodeJS.ErrnoException) {
146+
// Retry for possible timed out requests
147+
if (error.name === 'AbortError') return true;
148+
// Downlevel ECONNRESET to retry as it may be recoverable
149+
return ('code' in error && error.code === 'ECONNRESET') || error.message.includes('ECONNRESET');
150+
}

0 commit comments

Comments
 (0)