diff --git a/.changeset/poor-otters-give.md b/.changeset/poor-otters-give.md new file mode 100644 index 0000000000..200c37655c --- /dev/null +++ b/.changeset/poor-otters-give.md @@ -0,0 +1,9 @@ +--- +"wrangler": patch +--- + +fix: `wrangler pages deploy` should fail if deployment was unsuccessful + +If a Pages project fails to deploy, `wrangler pages deploy` will log +an error message, but exit successfully. It should instead throw a +`FatalError`. diff --git a/packages/wrangler/src/__tests__/pages/deploy.test.ts b/packages/wrangler/src/__tests__/pages/deploy.test.ts index ae8abc17dc..4044533448 100644 --- a/packages/wrangler/src/__tests__/pages/deploy.test.ts +++ b/packages/wrangler/src/__tests__/pages/deploy.test.ts @@ -2478,7 +2478,7 @@ and that at least one include rule is provided. expect(getProjectRequestCount).toEqual(2); }); - it("should show a failure message, and appropriate logs, if the deployment of a Functions project failed", async () => { + it("should fail with the appropriate error message, if the deployment of the project failed", async () => { // set up the directory of static files to upload. mkdirSync("public"); writeFileSync("public/README.md", "This is a readme"); @@ -2503,8 +2503,6 @@ and that at least one include rule is provided. "foo" ); - let getProjectRequestCount = 0; - msw.use( rest.post("*/pages/assets/check-missing", async (req, res, ctx) => { const body = (await req.json()) as { @@ -2657,8 +2655,6 @@ and that at least one include rule is provided. rest.get( "*/accounts/:accountId/pages/projects/foo", async (req, res, ctx) => { - getProjectRequestCount++; - expect(req.params.accountId).toEqual("some-account-id"); return res( @@ -2676,25 +2672,10 @@ and that at least one include rule is provided. ) ); - await runWrangler("pages deploy public --project-name=foo"); - - expect(getProjectRequestCount).toEqual(2); - expect(normalizeProgressSteps(std.out)).toMatchInlineSnapshot(` - "✨ Compiled Worker successfully - ✨ Success! Uploaded 1 files (TIMINGS) - - ✨ Uploading Functions bundle - 🌎 Deploying... - ❌ Deployment failed!" - `); - - expect(std.err).toMatchInlineSnapshot(` - "X [ERROR] Failed to publish your Function. Got error: Uncaught TypeError: a is not a function - - at functionsWorker-0.11031665179307093.js:41:1 - - " - `); + await expect(runWrangler("pages deploy public --project-name=foo")) + .rejects.toThrow(`Deployment failed! +Failed to publish your Function. Got error: Uncaught TypeError: a is not a function + at functionsWorker-0.11031665179307093.js:41:1`); }); }); @@ -4071,7 +4052,7 @@ and that at least one include rule is provided. expect(std.err).toMatchInlineSnapshot('""'); }); - it("should show a failure message, and appropriate logs, if the deployment of an Advanced Mode project failed", async () => { + it("should fail with the appropriate logs, if the deployment of the project failed", async () => { // set up the directory of static files to upload. mkdirSync("public"); writeFileSync("public/README.md", "This is a readme"); @@ -4099,7 +4080,6 @@ and that at least one include rule is provided. "foo" ); - let getProjectRequestCount = 0; msw.use( rest.post("*/pages/assets/check-missing", async (req, res, ctx) => { const body = (await req.json()) as { @@ -4236,8 +4216,6 @@ and that at least one include rule is provided. rest.get( "*/accounts/:accountId/pages/projects/foo", async (req, res, ctx) => { - getProjectRequestCount++; - expect(req.params.accountId).toEqual("some-account-id"); return res( @@ -4262,25 +4240,10 @@ and that at least one include rule is provided. ) ); - await runWrangler("pages deploy public --project-name=foo"); - - expect(getProjectRequestCount).toEqual(2); - expect(normalizeProgressSteps(std.out)).toMatchInlineSnapshot(` - "✨ Success! Uploaded 1 files (TIMINGS) - - ✨ Compiled Worker successfully - ✨ Uploading Worker bundle - 🌎 Deploying... - ❌ Deployment failed!" - `); - - expect(std.err).toMatchInlineSnapshot(` - "X [ERROR] Failed to publish your Function. Got error: Uncaught TypeError: a is not a function - - at functionsWorker-0.11031665179307093.js:41:1 - - " - `); + await expect(runWrangler("pages deploy public --project-name=foo")) + .rejects.toThrow(`Deployment failed! +Failed to publish your Function. Got error: Uncaught TypeError: a is not a function + at functionsWorker-0.11031665179307093.js:41:1`); }); }); diff --git a/packages/wrangler/src/pages/deploy.tsx b/packages/wrangler/src/pages/deploy.tsx index 398391fa8c..dabce578ce 100644 --- a/packages/wrangler/src/pages/deploy.tsx +++ b/packages/wrangler/src/pages/deploy.tsx @@ -409,10 +409,15 @@ export const Handler = async (args: PagesDeployArgs) => { `/accounts/${accountId}/pages/projects/${projectName}/deployments/${deploymentResponse.id}/history/logs?size=10000000` ); // last log entry will be the most relevant for Direct Uploads - const failureMessage = logs.data[logs.total - 1].line; + const failureMessage = logs.data[logs.total - 1].line + .replace("Error:", "") + .trim(); - logger.error(failureMessage.replace("Error:", "").trim()); - logger.log("❌ Deployment failed!"); + throw new FatalError( + `Deployment failed! +${failureMessage}`, + 1 + ); } else { logger.log( `✨ Deployment complete! However, we couldn't ascertain the final status of your deployment.\n\n` +