fix(telegram): retry transient 5xx download errors
This commit is contained in:
parent
e2c4993be7
commit
b54f823a03
@ -239,6 +239,31 @@ describe("resolveMedia getFile retry", () => {
|
||||
expect(fetchRemoteMedia).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("retries fetchRemoteMedia on transient HTTP 5xx error and succeeds", async () => {
|
||||
const getFile = vi.fn().mockResolvedValue({ file_path: "voice/file_0.oga" });
|
||||
fetchRemoteMedia
|
||||
.mockRejectedValueOnce(new MockMediaFetchError("http_error", "HTTP 502 Bad Gateway"))
|
||||
.mockResolvedValueOnce({
|
||||
buffer: Buffer.from("audio"),
|
||||
contentType: "audio/ogg",
|
||||
fileName: "file_0.oga",
|
||||
});
|
||||
saveMediaBuffer.mockResolvedValueOnce({
|
||||
path: "/tmp/file_0.oga",
|
||||
contentType: "audio/ogg",
|
||||
});
|
||||
|
||||
const promise = resolveMedia(makeCtx("voice", getFile), MAX_MEDIA_BYTES, BOT_TOKEN);
|
||||
await flushRetryTimers();
|
||||
const result = await promise;
|
||||
|
||||
expect(getFile).toHaveBeenCalledTimes(1);
|
||||
expect(fetchRemoteMedia).toHaveBeenCalledTimes(2);
|
||||
expect(result).toEqual(
|
||||
expect.objectContaining({ path: "/tmp/file_0.oga", placeholder: "<media:audio>" }),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not retry fetchRemoteMedia on max_bytes policy violation", async () => {
|
||||
const getFile = vi.fn().mockResolvedValue({ file_path: "video/large.mp4" });
|
||||
fetchRemoteMedia.mockRejectedValueOnce(
|
||||
|
||||
@ -66,9 +66,19 @@ function isRetryableGetFileError(err: unknown): boolean {
|
||||
*/
|
||||
function isRetryableDownloadError(err: unknown): boolean {
|
||||
if (err instanceof MediaFetchError) {
|
||||
// Only retry transient fetch failures (network issues, timeouts, connection drops).
|
||||
// Do not retry HTTP errors (4xx, 5xx) or policy violations (max_bytes).
|
||||
return err.code === "fetch_failed";
|
||||
// Retry transient fetch failures (network issues, timeouts, connection drops).
|
||||
if (err.code === "fetch_failed") {
|
||||
return true;
|
||||
}
|
||||
// Retry transient HTTP 5xx server errors; do not retry 4xx or policy violations.
|
||||
if (err.code === "http_error") {
|
||||
const match = /HTTP (\d{3})/.exec(err.message);
|
||||
if (match) {
|
||||
const status = Number(match[1]);
|
||||
return status >= 500;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// For non-MediaFetchError, check if it looks like a transient network error.
|
||||
const msg = formatErrorMessage(err).toLowerCase();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user