refactor: simplify telegram delivery and outbound session resolver flow

This commit is contained in:
Peter Steinberger
2026-03-02 03:08:33 +00:00
parent 166ae8f002
commit 493ebb915b
3 changed files with 450 additions and 314 deletions

View File

@@ -37,13 +37,34 @@ function isProxyLikeDispatcher(dispatcher: unknown): boolean {
return typeof ctorName === "string" && ctorName.includes("ProxyAgent");
}
const FALLBACK_RETRY_ERROR_CODES = new Set([
const FALLBACK_RETRY_ERROR_CODES = [
"ETIMEDOUT",
"ENETUNREACH",
"EHOSTUNREACH",
"UND_ERR_CONNECT_TIMEOUT",
"UND_ERR_SOCKET",
]);
] as const;
type Ipv4FallbackContext = {
message: string;
codes: Set<string>;
};
type Ipv4FallbackRule = {
name: string;
matches: (ctx: Ipv4FallbackContext) => boolean;
};
const IPV4_FALLBACK_RULES: readonly Ipv4FallbackRule[] = [
{
name: "fetch-failed-envelope",
matches: ({ message }) => message.includes("fetch failed"),
},
{
name: "known-network-code",
matches: ({ codes }) => FALLBACK_RETRY_ERROR_CODES.some((code) => codes.has(code)),
},
];
// Node 22 workaround: enable autoSelectFamily to allow IPv4 fallback on broken IPv6 networks.
// Many networks have IPv6 configured but not routed, causing "Network is unreachable" errors.
@@ -149,21 +170,17 @@ function collectErrorCodes(err: unknown): Set<string> {
}
function shouldRetryWithIpv4Fallback(err: unknown): boolean {
const message =
err && typeof err === "object" && "message" in err ? String(err.message).toLowerCase() : "";
if (!message.includes("fetch failed")) {
return false;
}
const codes = collectErrorCodes(err);
if (codes.size === 0) {
return false;
}
for (const code of codes) {
if (FALLBACK_RETRY_ERROR_CODES.has(code)) {
return true;
const ctx: Ipv4FallbackContext = {
message:
err && typeof err === "object" && "message" in err ? String(err.message).toLowerCase() : "",
codes: collectErrorCodes(err),
};
for (const rule of IPV4_FALLBACK_RULES) {
if (!rule.matches(ctx)) {
return false;
}
}
return false;
return true;
}
function applyTelegramIpv4Fallback(): void {