Skip to content

Commit 1a10050

Browse files
refactor(core): simplify mongo network retry helper
Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com>
1 parent 7ad82f5 commit 1a10050

2 files changed

Lines changed: 17 additions & 42 deletions

File tree

packages/core/src/util/mongo-network-error.util.ts

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,21 @@ const TRANSIENT_MONGO_ERROR_NAMES = new Set([
1111
]);
1212

1313
const TRANSIENT_MONGO_MESSAGE_PATTERNS = [
14-
/getaddrinfo\s+ESERVFAIL/i,
15-
/getaddrinfo\s+ENOTFOUND/i,
16-
/getaddrinfo\s+EAI_AGAIN/i,
17-
/\bECONNRESET\b/i,
18-
/\bETIMEDOUT\b/i,
19-
/\bECONNREFUSED\b/i,
14+
/getaddrinfo\s+(ESERVFAIL|ENOTFOUND|EAI_AGAIN)/i,
15+
/\b(ECONNRESET|ETIMEDOUT|ECONNREFUSED)\b/i,
2016
/server monitor timeout/i,
21-
/interrupted due to server monitor timeout/i,
2217
/connection.*(closed|reset|timed?\s*out)/i,
2318
/server selection timed?\s*out/i,
2419
/no connection available/i,
2520
/pool.*cleared/i,
2621
];
2722

28-
function errorName(error: unknown): string | undefined {
29-
if (!(error instanceof Error)) return undefined;
30-
return error.name;
31-
}
32-
33-
function errorMessage(error: unknown): string {
34-
if (error instanceof Error) return error.message;
35-
if (typeof error === "string") return error;
36-
return "";
37-
}
38-
3923
export function isTransientMongoNetworkError(error: unknown): boolean {
40-
const name = errorName(error);
41-
if (name !== undefined && TRANSIENT_MONGO_ERROR_NAMES.has(name)) {
42-
return true;
43-
}
44-
45-
const message = errorMessage(error);
46-
if (message.length === 0) return false;
47-
24+
if (!(error instanceof Error)) return false;
25+
if (TRANSIENT_MONGO_ERROR_NAMES.has(error.name)) return true;
26+
if (error.message.length === 0) return false;
4827
return TRANSIENT_MONGO_MESSAGE_PATTERNS.some((pattern) =>
49-
pattern.test(message),
28+
pattern.test(error.message),
5029
);
5130
}
5231

@@ -64,18 +43,16 @@ export async function withTransientMongoRetry<T>(
6443
options.sleep ??
6544
((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
6645

67-
let lastError: unknown;
68-
for (let attempt = 1; attempt <= attempts; attempt += 1) {
46+
let attempt = 0;
47+
while (true) {
48+
attempt += 1;
6949
try {
7050
return await operation();
7151
} catch (error) {
72-
lastError = error;
73-
const canRetry =
74-
attempt < attempts && isTransientMongoNetworkError(error);
75-
if (!canRetry) throw error;
52+
if (attempt >= attempts || !isTransientMongoNetworkError(error)) {
53+
throw error;
54+
}
7655
await sleep(delayMs * attempt);
7756
}
7857
}
79-
80-
throw lastError;
8158
}

packages/sync/src/app.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,11 @@ function buildHealthSnapshotSweep(
345345
// SweepScheduler always passes `before`; health ignore it and use now.
346346
sweep: async () => {
347347
// A single Atlas/DNS blip must not skip the whole 5-minute gauge.
348-
await withTransientMongoRetry(
349-
() =>
350-
emitHealthSnapshot({
351-
deps: { mongo, identity },
352-
client,
353-
}),
354-
{ attempts: 3, delayMs: 250 },
348+
await withTransientMongoRetry(() =>
349+
emitHealthSnapshot({
350+
deps: { mongo, identity },
351+
client,
352+
}),
355353
);
356354
return 1;
357355
},

0 commit comments

Comments
 (0)