Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[D1] Add user friendly D1 validation error messages for dev --remote and deploy #4914

Merged
merged 9 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions packages/wrangler/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,10 @@
) {
err.preventReport();

if(err.notes[0].text === "binding DB of type d1 must have a valid `id` specified [code: 10021]") {
nora-soderlund marked this conversation as resolved.
Show resolved Hide resolved
throw new UserError("You must use a real database in the database_id configuration. You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here: https://developers.cloudflare.com/d1/configuration/local-development");

Check warning on line 723 in packages/wrangler/src/deploy/deploy.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/deploy/deploy.ts#L723

Added line #L723 was not covered by tests
}

const maybeNameToFilePath = (moduleName: string) => {
// If this is a service worker, always return the entrypoint path.
// Service workers can't have additional JavaScript modules.
Expand Down
123 changes: 82 additions & 41 deletions packages/wrangler/src/dev/remote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
CfPreviewToken,
} from "./create-worker-preview";
import type { EsbuildBundle } from "./use-esbuild";
import type { ParseError } from "../parse";

interface RemoteProps {
name: string | undefined;
Expand Down Expand Up @@ -336,29 +337,20 @@
start().catch((err) => {
// we want to log the error, but not end the process
// since it could recover after the developer fixes whatever's wrong
if ((err as { code: string }).code !== "ABORT_ERR") {
// instead of logging the raw API error to the user,
// give them friendly instructions
// for error 10063 (workers.dev subdomain required)
if (err.code === 10063) {
const errorMessage =
"Error: You need to register a workers.dev subdomain before running the dev command in remote mode";
const solutionMessage =
"You can either enable local mode by pressing l, or register a workers.dev subdomain here:";
const onboardingLink = `https://dash.cloudflare.com/${props.accountId}/workers/onboarding`;
logger.error(
`${errorMessage}\n${solutionMessage}\n${onboardingLink}`
);
} else if (err.code === 10049) {
logger.log("Preview token expired, fetching a new one");
// code 10049 happens when the preview token expires
// since we want a new preview token when this happens,
// lets increment the counter, and trigger a rerun of
// the useEffect above
setRestartCounter((prevCount) => prevCount + 1);
} else {
logger.error("Error on remote worker:", err);
}
// instead of logging the raw API error to the user,
// give them friendly instructions

// code 10049 happens when the preview token expires
if(err.code === 10049) {
logger.log("Preview token expired, fetching a new one");

Check warning on line 345 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L345

Added line #L345 was not covered by tests

// since we want a new preview token when this happens,
// lets increment the counter, and trigger a rerun of
// the useEffect above
setRestartCounter((prevCount) => prevCount + 1);

Check warning on line 350 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L350

Added line #L350 was not covered by tests
}
else if(!handleUserFriendlyError(err, props.accountId)) {
logger.error("Error on remote worker:", err);

Check warning on line 353 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L353

Added line #L353 was not covered by tests
}
});

Expand Down Expand Up @@ -525,24 +517,18 @@
return workerPreviewToken;
}
return start().catch((err) => {
if ((err as { code?: string })?.code !== "ABORT_ERR") {
// instead of logging the raw API error to the user,
// give them friendly instructions
// for error 10063 (workers.dev subdomain required)
if (err?.code === 10063) {
const errorMessage =
"Error: You need to register a workers.dev subdomain before running the dev command in remote mode";
const solutionMessage =
"You can either enable local mode by pressing l, or register a workers.dev subdomain here:";
const onboardingLink = `https://dash.cloudflare.com/${props.accountId}/workers/onboarding`;
logger.error(`${errorMessage}\n${solutionMessage}\n${onboardingLink}`);
} else if (err?.code === 10049) {
// code 10049 happens when the preview token expires
logger.log("Preview token expired, restart server to fetch a new one");
} else {
helpIfErrorIsSizeOrScriptStartup(err, props.bundle?.dependencies || {});
logger.error("Error on remote worker:", err);
}
// we want to log the error, but not end the process
// since it could recover after the developer fixes whatever's wrong
// instead of logging the raw API error to the user,
// give them friendly instructions

// code 10049 happens when the preview token expires
if(err.code === 10049) {
logger.log("Preview token expired, restart server to fetch a new one");

Check warning on line 527 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L527

Added line #L527 was not covered by tests
}
else if(!handleUserFriendlyError(err, props.accountId)) {
helpIfErrorIsSizeOrScriptStartup(err, props.bundle?.dependencies || {});
logger.error("Error on remote worker:", err);

Check warning on line 531 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L531

Added line #L531 was not covered by tests
}
});
}
Expand Down Expand Up @@ -684,3 +670,58 @@
</>
);
}

/**
* A switch for handling thrown error mappings to user friendly
* messages, does not perform any logic other than logging errors.
* @returns if the error was handled or not
*/
function handleUserFriendlyError(error: ParseError, accountId?: string) {

Check warning on line 679 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L679

Added line #L679 was not covered by tests
// simulate aborts as handled errors by this function, but don't
// log anything
if ((error as unknown as { code: string }).code === "ABORT_ERR") {
return true;

Check warning on line 683 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L683

Added line #L683 was not covered by tests
}

switch((error as unknown as { code: number }).code) {
// code 10021 is a validation error
case 10021: {

Check warning on line 688 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L688

Added line #L688 was not covered by tests
// if it is the following message, give a more user friendly
// error, otherwise do not handle this error in this function
if(error.notes[0].text === "binding DB of type d1 must have a valid `id` specified [code: 10021]") {
const errorMessage =
"Error: You must use a real database in the preview_database_id configuration.";

Check warning on line 693 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L693

Added line #L693 was not covered by tests
const solutionMessage =
"You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here:";
const documentationLink = `https://developers.cloudflare.com/d1/configuration/local-development`;

Check warning on line 696 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L695-L696

Added lines #L695 - L696 were not covered by tests

logger.error(

Check warning on line 698 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L698

Added line #L698 was not covered by tests
`${errorMessage}\n${solutionMessage}\n${documentationLink}`
);

return true;

Check warning on line 702 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L702

Added line #L702 was not covered by tests
}

return false;

Check warning on line 705 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L705

Added line #L705 was not covered by tests
}

// for error 10063 (workers.dev subdomain required)
case 10063: {

Check warning on line 709 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L709

Added line #L709 was not covered by tests
const errorMessage =
"Error: You need to register a workers.dev subdomain before running the dev command in remote mode";

Check warning on line 711 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L711

Added line #L711 was not covered by tests
const solutionMessage =
"You can either enable local mode by pressing l, or register a workers.dev subdomain here:";

Check warning on line 713 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L713

Added line #L713 was not covered by tests
const onboardingLink = (accountId)?(`https://dash.cloudflare.com/${accountId}/workers/onboarding`):("https://dash.cloudflare.com/?to=/:account/workers/onboarding");

logger.error(

Check warning on line 716 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L716

Added line #L716 was not covered by tests
`${errorMessage}\n${solutionMessage}\n${onboardingLink}`
);

return true;

Check warning on line 720 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L720

Added line #L720 was not covered by tests
}

default: {
return false;

Check warning on line 724 in packages/wrangler/src/dev/remote.tsx

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/dev/remote.tsx#L723-L724

Added lines #L723 - L724 were not covered by tests
}
}
}
Loading