Skip to content

Commit 7bd7c75

Browse files
committed
WC-6008 [wrangler] previews: return proper stdout for --json
1 parent 629ddef commit 7bd7c75

3 files changed

Lines changed: 92 additions & 7 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"wrangler": minor
3+
---
4+
5+
Return structured configuration errors from `wrangler preview --json`
6+
7+
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.

packages/wrangler/src/__tests__/preview.test.ts

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,9 +1214,13 @@ describe("wrangler preview", () => {
12141214
runWrangler(
12151215
"preview --name test-preview --config wrangler.json --json --ignore-base-config"
12161216
)
1217-
).rejects.toThrow("missing a `previews` block");
1217+
).rejects.toThrow("missing a previews block");
12181218

12191219
expect(std.warn).not.toContain(namedEnvironmentsMessage);
1220+
expect(JSON.parse(std.out)).toEqual({
1221+
error: "Your Wrangler configuration is missing a previews block",
1222+
suggested_config: { previews: {} },
1223+
});
12201224
});
12211225

12221226
test.for(["wrangler.toml", "wrangler.json", "wrangler.jsonc"])(
@@ -1642,12 +1646,13 @@ describe("wrangler preview", () => {
16421646
runWrangler(
16431647
"preview --name test-preview --config wrangler.json --json"
16441648
)
1645-
).rejects.toThrow(
1646-
'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'
1647-
);
1649+
).rejects.toThrow("missing a previews block");
16481650

16491651
expect(deploymentRequests).toBe(0);
1650-
expect(std.out).toBe("");
1652+
expect(JSON.parse(std.out)).toEqual({
1653+
error: "Your Wrangler configuration is missing a previews block",
1654+
suggested_config: { previews: {} },
1655+
});
16511656
expect(std.info).toBe("");
16521657
expect(readFileSync("wrangler.json", "utf8")).toBe(originalConfig);
16531658
});
@@ -1805,9 +1810,16 @@ describe("wrangler preview", () => {
18051810
runWrangler(
18061811
"preview --name test-preview --config wrangler.json --json"
18071812
)
1808-
).rejects.toThrow("missing a `previews` block");
1813+
).rejects.toThrow("missing a previews block");
18091814

1810-
expect(std.out).toBe("");
1815+
expect(JSON.parse(std.out)).toEqual({
1816+
error: "Your Wrangler configuration is missing a previews block",
1817+
suggested_config: {
1818+
previews: {
1819+
vars: { API_URL: "https://preview.example.com" },
1820+
},
1821+
},
1822+
});
18111823
expect(std.info).toBe("");
18121824
expect(readFileSync("wrangler.json", "utf8")).toBe(originalConfig);
18131825
});
@@ -2133,6 +2145,39 @@ describe("wrangler preview", () => {
21332145
);
21342146
});
21352147

2148+
test("returns the suggested Preview configuration as JSON", async ({
2149+
expect,
2150+
}) => {
2151+
writeWranglerConfig(
2152+
{
2153+
name: "test-worker",
2154+
main: "src/index.ts",
2155+
kv_namespaces: [
2156+
{ binding: "SESSIONS", id: "production-sessions-kv-id" },
2157+
],
2158+
},
2159+
"wrangler.json"
2160+
);
2161+
2162+
await expect(
2163+
runWrangler("preview --name test-preview --json")
2164+
).rejects.toThrow("missing a previews block");
2165+
2166+
expect(JSON.parse(std.out)).toEqual({
2167+
error: "Your Wrangler configuration is missing a previews block",
2168+
suggested_config: {
2169+
previews: {
2170+
kv_namespaces: [{ binding: "SESSIONS", id: "<REPLACE_ME>" }],
2171+
},
2172+
},
2173+
messages: [
2174+
"Replace each <REPLACE_ME> placeholder with a Preview-safe value. Do not use production resources unless you intend for this Preview to access them.",
2175+
],
2176+
});
2177+
expect(std.warn).toBe("");
2178+
expect(std.err).toBe("");
2179+
});
2180+
21362181
test.for([
21372182
{
21382183
name: "Durable Objects",
@@ -2178,6 +2223,20 @@ describe("wrangler preview", () => {
21782223
).rejects.toThrow("needs a `previews` block to run this command");
21792224

21802225
expect(std.warn).toContain(warning);
2226+
std.getAndClearOut();
2227+
2228+
await expect(
2229+
runWrangler(
2230+
"preview --name test-preview --config wrangler.json --ignore-base-config --json"
2231+
)
2232+
).rejects.toThrow("missing a previews block");
2233+
2234+
const jsonError = JSON.parse(std.out) as {
2235+
messages: string[];
2236+
};
2237+
expect(jsonError.messages).toEqual(
2238+
expect.arrayContaining([expect.stringContaining(warning)])
2239+
);
21812240
}
21822241
);
21832242

packages/wrangler/src/preview/ensure-config.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
formatConfigSnippet,
1111
isNonInteractiveOrCI,
1212
JSON_CONFIG_FORMATS,
13+
JsonFriendlyFatalError,
1314
UserError,
1415
} from "@cloudflare/workers-utils";
1516
import { confirm } from "../dialogs";
@@ -166,6 +167,24 @@ export async function ensurePreviewsConfig(
166167
}
167168
const missingPreviewsConfigMessage =
168169
missingPreviewsConfigParagraphs.join("\n");
170+
if (args.json) {
171+
throw new JsonFriendlyFatalError(
172+
JSON.stringify(
173+
{
174+
error: "Your Wrangler configuration is missing a previews block",
175+
suggested_config: proposedConfigPatch,
176+
...(conversionMessages.length > 0 && {
177+
messages: conversionMessages,
178+
}),
179+
},
180+
null,
181+
2
182+
),
183+
{
184+
telemetryMessage: "preview command previews configuration missing",
185+
}
186+
);
187+
}
169188

170189
if (hasBlockingDeploymentMessages) {
171190
logConversionMessages(conversionMessages, args.json);

0 commit comments

Comments
 (0)