fix(telegram): handle Grammy HttpError network failures (#3815) (#7195)

* fix(telegram): handle Grammy HttpError network failures (#3815)

Grammy wraps fetch errors in an .error property (not .cause). Added .error
traversal to collectErrorCandidates in network-errors.ts.

Registered scoped unhandled rejection handler in monitorTelegramProvider
to catch network errors that escape the polling loop (e.g., from setMyCommands
during bot setup). Handler is unregistered when the provider stops.

* fix(telegram): address review feedback for Grammy HttpError handling

- Gate .error traversal on HttpError name to avoid widening search graph
- Use runtime logger instead of console.warn for consistency
- Add isGrammyHttpError check to scope unhandled rejection handler
- Consolidate isNetworkRelatedError into isRecoverableTelegramNetworkError
- Add 'timeout' to recoverable message snippets for full coverage
This commit is contained in:
Christian Klotz
2026-02-02 15:25:41 +00:00
committed by GitHub
parent f9fae2c439
commit 99b4f2a24e
3 changed files with 164 additions and 111 deletions

View File

@@ -36,6 +36,7 @@ const RECOVERABLE_MESSAGE_SNIPPETS = [
"client network socket disconnected",
"socket hang up",
"getaddrinfo",
"timeout", // catch timeout messages not covered by error codes/names
];
function normalizeCode(code?: string): string {
@@ -97,6 +98,14 @@ function collectErrorCandidates(err: unknown): unknown[] {
}
}
}
// Grammy's HttpError wraps the underlying error in .error (not .cause)
// Only follow .error for HttpError to avoid widening the search graph
if (getErrorName(current) === "HttpError") {
const wrappedError = (current as { error?: unknown }).error;
if (wrappedError && !seen.has(wrappedError)) {
queue.push(wrappedError);
}
}
}
}