|
4 | 4 | ListObjectsV2Command, |
5 | 5 | GetObjectCommand, |
6 | 6 | } from "@aws-sdk/client-s3"; |
| 7 | +import pRetry, { AbortError } from "p-retry"; |
7 | 8 |
|
8 | 9 | function checkEnvVariable(variableName: string) { |
9 | 10 | const value = process.env[variableName]; |
@@ -63,13 +64,47 @@ export async function listDirectory(directoryName: string) { |
63 | 64 | export async function getFileContent(fileName: string) { |
64 | 65 | const { B2_BUCKET_NAME } = getVariables(); |
65 | 66 | const s3 = getS3Client(); |
66 | | - const fileContent = await s3.send( |
67 | | - new GetObjectCommand({ |
68 | | - Bucket: B2_BUCKET_NAME, |
69 | | - Key: fileName, |
70 | | - }) |
| 67 | + |
| 68 | + const result = await pRetry( |
| 69 | + async (attempt) => { |
| 70 | + try { |
| 71 | + const fileContent = await s3.send( |
| 72 | + new GetObjectCommand({ |
| 73 | + Bucket: B2_BUCKET_NAME, |
| 74 | + Key: fileName, |
| 75 | + }) |
| 76 | + ); |
| 77 | + return (await fileContent.Body?.transformToString()) ?? ""; |
| 78 | + } catch (error) { |
| 79 | + const code = (error as any)?.code as string | undefined; |
| 80 | + const message = (error as any)?.message as string | undefined; |
| 81 | + const isTransient = |
| 82 | + code === "ECONNRESET" || |
| 83 | + code === "ENOTFOUND" || |
| 84 | + code === "ETIMEDOUT" || |
| 85 | + code === "ECONNREFUSED" || |
| 86 | + (message && message.includes("socket connection was closed unexpectedly")); |
| 87 | + |
| 88 | + if (!isTransient) { |
| 89 | + throw new AbortError(error as Error); |
| 90 | + } |
| 91 | + |
| 92 | + console.warn( |
| 93 | + `⚠️ B2 getFileContent transient error (attempt ${attempt}): ${code || message}` |
| 94 | + ); |
| 95 | + throw error; |
| 96 | + } |
| 97 | + }, |
| 98 | + { |
| 99 | + retries: 3, |
| 100 | + factor: 2, |
| 101 | + minTimeout: 2000, |
| 102 | + maxTimeout: 10000, |
| 103 | + randomize: false, |
| 104 | + } |
71 | 105 | ); |
72 | | - return (await fileContent.Body?.transformToString()) ?? ""; |
| 106 | + |
| 107 | + return result; |
73 | 108 | } |
74 | 109 |
|
75 | 110 | export async function checkFileExists(fileName: string): Promise<boolean> { |
|
0 commit comments