Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/quiet-previews-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": minor
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Comment thread
podonnell-dev marked this conversation as resolved.
---

Return structured configuration errors from `wrangler preview --json`

When a Worker is missing its Preview configuration, JSON mode now returns an `error`, a `suggested_config` patch, and any associated onboarding `messages` without interactive output or terminal formatting. This changes the private-beta Preview command to make automated onboarding reliable.
73 changes: 66 additions & 7 deletions packages/wrangler/src/__tests__/preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1214,9 +1214,13 @@ describe("wrangler preview", () => {
runWrangler(
"preview --name test-preview --config wrangler.json --json --ignore-base-config"
)
).rejects.toThrow("missing a `previews` block");
).rejects.toThrow("missing a previews block");

expect(std.warn).not.toContain(namedEnvironmentsMessage);
expect(JSON.parse(std.out)).toEqual({
error: "Your Wrangler configuration is missing a previews block",
suggested_config: { previews: {} },
});
});

test.for(["wrangler.toml", "wrangler.json", "wrangler.jsonc"])(
Expand Down Expand Up @@ -1642,12 +1646,13 @@ describe("wrangler preview", () => {
runWrangler(
"preview --name test-preview --config wrangler.json --json"
)
).rejects.toThrow(
'Your Wrangler configuration is missing a `previews` block to run this command. Add the following to your configuration file:\n{\n "previews": {}\n}\nTo create or update a Preview with `npx wrangler preview`, your Wrangler configuration must include a `previews` block. The block can be empty. Assets, compatibility settings, migrations, and placement stay at the top level and do not need to be added to `previews`.\nLearn more: https://developers.cloudflare.com/workers/previews/configuration/#wrangler-configuration-file'
);
).rejects.toThrow("missing a previews block");

expect(deploymentRequests).toBe(0);
expect(std.out).toBe("");
expect(JSON.parse(std.out)).toEqual({
error: "Your Wrangler configuration is missing a previews block",
suggested_config: { previews: {} },
});
expect(std.info).toBe("");
expect(readFileSync("wrangler.json", "utf8")).toBe(originalConfig);
});
Expand Down Expand Up @@ -1805,9 +1810,16 @@ describe("wrangler preview", () => {
runWrangler(
"preview --name test-preview --config wrangler.json --json"
)
).rejects.toThrow("missing a `previews` block");
).rejects.toThrow("missing a previews block");

expect(std.out).toBe("");
expect(JSON.parse(std.out)).toEqual({
error: "Your Wrangler configuration is missing a previews block",
suggested_config: {
previews: {
vars: { API_URL: "https://preview.example.com" },
},
},
});
expect(std.info).toBe("");
expect(readFileSync("wrangler.json", "utf8")).toBe(originalConfig);
});
Expand Down Expand Up @@ -2133,6 +2145,39 @@ describe("wrangler preview", () => {
);
});

test("returns the suggested Preview configuration as JSON", async ({
expect,
}) => {
writeWranglerConfig(
{
name: "test-worker",
main: "src/index.ts",
kv_namespaces: [
{ binding: "SESSIONS", id: "production-sessions-kv-id" },
],
},
"wrangler.json"
);

await expect(
runWrangler("preview --name test-preview --json")
).rejects.toThrow("missing a previews block");

expect(JSON.parse(std.out)).toEqual({
error: "Your Wrangler configuration is missing a previews block",
suggested_config: {
previews: {
kv_namespaces: [{ binding: "SESSIONS", id: "<REPLACE_ME>" }],
},
},
messages: [
"Replace each <REPLACE_ME> placeholder with a Preview-safe value. Do not use production resources unless you intend for this Preview to access them.",
],
});
expect(std.warn).toBe("");
expect(std.err).toBe("");
});

test.for([
{
name: "Durable Objects",
Expand Down Expand Up @@ -2178,6 +2223,20 @@ describe("wrangler preview", () => {
).rejects.toThrow("needs a `previews` block to run this command");

expect(std.warn).toContain(warning);
std.getAndClearOut();

await expect(
runWrangler(
"preview --name test-preview --config wrangler.json --ignore-base-config --json"
)
).rejects.toThrow("missing a previews block");

const jsonError = JSON.parse(std.out) as {
messages: string[];
};
expect(jsonError.messages).toEqual(
expect.arrayContaining([expect.stringContaining(warning)])
);
}
);

Expand Down
19 changes: 19 additions & 0 deletions packages/wrangler/src/preview/ensure-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
formatConfigSnippet,
isNonInteractiveOrCI,
JSON_CONFIG_FORMATS,
JsonFriendlyFatalError,
UserError,
} from "@cloudflare/workers-utils";
import { confirm } from "../dialogs";
Expand Down Expand Up @@ -166,6 +167,24 @@ export async function ensurePreviewsConfig(
}
const missingPreviewsConfigMessage =
missingPreviewsConfigParagraphs.join("\n");
if (args.json) {
throw new JsonFriendlyFatalError(
JSON.stringify(
{
error: "Your Wrangler configuration is missing a previews block",
suggested_config: proposedConfigPatch,
...(conversionMessages.length > 0 && {
messages: conversionMessages,
}),
},
null,
2
),
{
telemetryMessage: "preview command previews configuration missing",
}
);
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
}

if (hasBlockingDeploymentMessages) {
logConversionMessages(conversionMessages, args.json);
Expand Down
Loading