Skip to content

Commit 7f6a90f

Browse files
committed
fix(service-error-classification): treat Node.js network errors as transient
1 parent 4642e7e commit 7f6a90f

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

packages/service-error-classification/src/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,8 @@ export const TRANSIENT_ERROR_STATUS_CODES = [500, 502, 503, 504];
5050
* Node.js system error codes that indicate timeout.
5151
*/
5252
export const NODEJS_TIMEOUT_ERROR_CODES = ["ECONNRESET", "ECONNREFUSED", "EPIPE", "ETIMEDOUT"];
53+
54+
/**
55+
* Node.js system error codes that indicate network error.
56+
*/
57+
export const NODEJS_NETWORK_ERROR_CODES = ["ENOTFOUND"];

packages/service-error-classification/src/index.spec.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { describe, expect, test as it } from "vitest";
33

44
import {
55
CLOCK_SKEW_ERROR_CODES,
6+
NODEJS_NETWORK_ERROR_CODES,
7+
NODEJS_TIMEOUT_ERROR_CODES,
68
THROTTLING_ERROR_CODES,
79
TRANSIENT_ERROR_CODES,
810
TRANSIENT_ERROR_STATUS_CODES,
@@ -16,15 +18,17 @@ const checkForErrorType = (
1618
httpStatusCode?: number;
1719
$retryable?: RetryableTrait;
1820
cause?: Partial<Error>;
21+
code?: string;
1922
},
2023
errorTypeResult: boolean
2124
) => {
22-
const { name, httpStatusCode, $retryable, cause } = options;
25+
const { name, httpStatusCode, $retryable, cause, code } = options;
2326
const error = Object.assign(new Error(), {
2427
name,
2528
$metadata: { httpStatusCode },
2629
$retryable,
2730
cause,
31+
code,
2832
});
2933
expect(isErrorTypeFunc(error as SdkError)).toBe(errorTypeResult);
3034
};
@@ -141,6 +145,18 @@ describe("isTransientError", () => {
141145
error.cause = error;
142146
checkForErrorType(isTransientError, { cause: error }, false);
143147
});
148+
149+
NODEJS_TIMEOUT_ERROR_CODES.forEach((code) => {
150+
it(`should declare error with cause with the code "${code}" to be a Transient error`, () => {
151+
checkForErrorType(isTransientError, { code }, true);
152+
});
153+
});
154+
155+
NODEJS_NETWORK_ERROR_CODES.forEach((code) => {
156+
it(`should declare error with cause with the code "${code}" to be a Transient error`, () => {
157+
checkForErrorType(isTransientError, { code }, true);
158+
});
159+
});
144160
});
145161

146162
describe("isServerError", () => {

packages/service-error-classification/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { SdkError } from "@smithy/types";
22

33
import {
44
CLOCK_SKEW_ERROR_CODES,
5+
NODEJS_NETWORK_ERROR_CODES,
56
NODEJS_TIMEOUT_ERROR_CODES,
67
THROTTLING_ERROR_CODES,
78
TRANSIENT_ERROR_CODES,
@@ -57,6 +58,7 @@ export const isTransientError = (error: SdkError, depth = 0): boolean =>
5758
isClockSkewCorrectedError(error) ||
5859
TRANSIENT_ERROR_CODES.includes(error.name) ||
5960
NODEJS_TIMEOUT_ERROR_CODES.includes((error as { code?: string })?.code || "") ||
61+
NODEJS_NETWORK_ERROR_CODES.includes((error as { code?: string })?.code || "") ||
6062
TRANSIENT_ERROR_STATUS_CODES.includes(error.$metadata?.httpStatusCode || 0) ||
6163
isBrowserNetworkError(error) ||
6264
(error.cause !== undefined && depth <= 10 && isTransientError(error.cause, depth + 1));

0 commit comments

Comments
 (0)