Skip to content

Commit e04e180

Browse files
[wrangler] Improve asset upload retry log message (#13990)
1 parent a5c9365 commit e04e180

3 files changed

Lines changed: 84 additions & 1 deletion

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Improve the log message shown when an asset upload attempt fails and is retried
6+
7+
The retry message now reports which attempt is being made (e.g. `Asset upload failed. Retrying... 1 of 5 attempts.`), making it easier to gauge how close Wrangler is to exhausting its retry budget. The raw error object is no longer appended to this user-facing message; it is instead logged at debug level (visible via `WRANGLER_LOG=debug`).

packages/wrangler/src/__tests__/deploy/assets.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,5 +1326,76 @@ describe("deploy", () => {
13261326
`[Error: An unexpected response has been received from the Cloudflare API for assets upload. Please try again.]`
13271327
);
13281328
});
1329+
1330+
it("should retry asset uploads on failure and log a retry message including the attempt count", async ({
1331+
expect,
1332+
}) => {
1333+
vi.stubEnv("WRANGLER_LOG", "debug");
1334+
1335+
const assets = [{ filePath: "file-1.txt", content: "Content of file-1" }];
1336+
writeAssets(assets);
1337+
writeWranglerConfig({
1338+
assets: { directory: "assets" },
1339+
});
1340+
1341+
const mockBuckets = [["0de3dd5df907418e9730fd2bd747bd5e"]];
1342+
await mockAUSRequest([], mockBuckets, "<<aus-token>>");
1343+
1344+
// Fail the first upload attempt, succeed on the second.
1345+
const uploadAttempts: Request[] = [];
1346+
msw.use(
1347+
http.post(
1348+
"*/accounts/some-account-id/workers/assets/upload",
1349+
async ({ request }) => {
1350+
uploadAttempts.push(request);
1351+
if (uploadAttempts.length === 1) {
1352+
return HttpResponse.json(
1353+
{
1354+
success: false,
1355+
errors: [{ code: 1, message: "upload-boom-from-test" }],
1356+
messages: [],
1357+
result: null,
1358+
},
1359+
{ status: 500 }
1360+
);
1361+
}
1362+
return HttpResponse.json(
1363+
{
1364+
success: true,
1365+
errors: [],
1366+
messages: [],
1367+
result: { jwt: "<<aus-completion-token>>" },
1368+
},
1369+
{ status: 201 }
1370+
);
1371+
}
1372+
)
1373+
);
1374+
1375+
mockSubDomainRequest();
1376+
mockUploadWorkerRequest({
1377+
expectedAssets: {
1378+
jwt: "<<aus-completion-token>>",
1379+
config: {},
1380+
},
1381+
expectedType: "none",
1382+
});
1383+
1384+
await runWrangler("deploy");
1385+
1386+
// The upload endpoint was hit twice: once failing, once succeeding.
1387+
expect(uploadAttempts.length).toBe(2);
1388+
1389+
// The new info message includes the attempt count.
1390+
expect(std.info).toContain(
1391+
"Asset upload failed. Retrying... 1 of 5 attempts."
1392+
);
1393+
1394+
// The error details no longer leak into the user-facing info log.
1395+
expect(std.info).not.toContain("upload-boom-from-test");
1396+
1397+
// The error is now logged at debug level instead.
1398+
expect(std.debug).toContain("upload-boom-from-test");
1399+
});
13291400
});
13301401
});

packages/wrangler/src/assets.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,12 @@ export const syncAssets = async (
193193
return res;
194194
} catch (e) {
195195
if (attempts < MAX_UPLOAD_ATTEMPTS) {
196-
logger.info(chalk.dim(`Asset upload failed. Retrying...\n`, e));
196+
logger.info(
197+
chalk.dim(
198+
`Asset upload failed. Retrying... ${attempts + 1} of ${MAX_UPLOAD_ATTEMPTS} attempts.\n`
199+
)
200+
);
201+
logger.debug(e);
197202
// Exponential backoff, 1 second first time, then 2 second, then 4 second etc.
198203
await new Promise((resolvePromise) =>
199204
setTimeout(resolvePromise, Math.pow(2, attempts) * 1000)

0 commit comments

Comments
 (0)