@gallop.software/studio 1.5.7 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -217,18 +217,30 @@ async function downloadFromCdn(originalPath) {
217
217
  const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME;
218
218
  if (!bucketName) throw new Error("R2 bucket not configured");
219
219
  const r2 = getR2Client();
220
- const response = await r2.send(
221
- new (0, _clients3.GetObjectCommand)({
222
- Bucket: bucketName,
223
- Key: originalPath.replace(/^\//, "")
224
- })
225
- );
226
- const stream = response.Body;
227
- const chunks = [];
228
- for await (const chunk of stream) {
229
- chunks.push(Buffer.from(chunk));
220
+ const maxRetries = 3;
221
+ let lastError;
222
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
223
+ try {
224
+ const response = await r2.send(
225
+ new (0, _clients3.GetObjectCommand)({
226
+ Bucket: bucketName,
227
+ Key: originalPath.replace(/^\//, "")
228
+ })
229
+ );
230
+ const stream = response.Body;
231
+ const chunks = [];
232
+ for await (const chunk of stream) {
233
+ chunks.push(Buffer.from(chunk));
234
+ }
235
+ return Buffer.concat(chunks);
236
+ } catch (error) {
237
+ lastError = error;
238
+ if (attempt < maxRetries - 1) {
239
+ await new Promise((resolve) => setTimeout(resolve, 500 * (attempt + 1)));
240
+ }
241
+ }
230
242
  }
231
- return Buffer.concat(chunks);
243
+ throw lastError || new Error(`Failed to download ${originalPath} after ${maxRetries} attempts`);
232
244
  }
233
245
  async function uploadToCdn(imageKey) {
234
246
  const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME;
@@ -260,12 +272,24 @@ async function deleteLocalThumbnails(imageKey) {
260
272
  }
261
273
  }
262
274
  async function downloadFromRemoteUrl(url) {
263
- const response = await fetch(url);
264
- if (!response.ok) {
265
- throw new Error(`Failed to download from ${url}: ${response.status}`);
275
+ const maxRetries = 3;
276
+ let lastError;
277
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
278
+ try {
279
+ const response = await fetch(url);
280
+ if (!response.ok) {
281
+ throw new Error(`Failed to download from ${url}: ${response.status}`);
282
+ }
283
+ const arrayBuffer = await response.arrayBuffer();
284
+ return Buffer.from(arrayBuffer);
285
+ } catch (error) {
286
+ lastError = error;
287
+ if (attempt < maxRetries - 1) {
288
+ await new Promise((resolve) => setTimeout(resolve, 500 * (attempt + 1)));
289
+ }
290
+ }
266
291
  }
267
- const arrayBuffer = await response.arrayBuffer();
268
- return Buffer.from(arrayBuffer);
292
+ throw lastError || new Error(`Failed to download from ${url} after ${maxRetries} attempts`);
269
293
  }
270
294
  async function uploadOriginalToCdn(imageKey) {
271
295
  const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME;