Skip to content

Commit

Permalink
Fix: provide proper error message for missing DOs (#4337)
Browse files Browse the repository at this point in the history
  • Loading branch information
Skye-31 committed Nov 7, 2023
1 parent f867e01 commit 6c8f41f
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 57 deletions.
7 changes: 7 additions & 0 deletions .changeset/rude-eagles-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

Improve the error message when a script isn't exported a Durable Object class

Previously, wrangler would error with a message like `Uncaught TypeError: Class extends value undefined is not a constructor or null`. This improves that messaging to be more understandable to users.
20 changes: 20 additions & 0 deletions fixtures/durable-objects-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "do-worker-app",
"version": "1.0.0",
"private": true,
"description": "",
"license": "ISC",
"author": "",
"main": "src/index.js",
"scripts": {
"dev": "wrangler deploy --dry-run",
"test": "npx vitest run",
"test:ci": "npx vitest run",
"test:watch": "npx vitest"
},
"devDependencies": {
"@cloudflare/workers-tsconfig": "workspace:^",
"undici": "^5.23.0",
"wrangler": "workspace:*"
}
}
5 changes: 5 additions & 0 deletions fixtures/durable-objects-app/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
async fetch() {
return new Response("foo");
},
};
29 changes: 29 additions & 0 deletions fixtures/durable-objects-app/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { resolve } from "node:path";
import { assert, describe, it } from "vitest";
import { execSync } from "node:child_process";

describe("durable objects", () => {
it("should throw an error when the worker doesn't export a durable object but requires one", ({
expect,
}) => {
let err: string = "";
try {
execSync("pnpm run dev", {
cwd: resolve(__dirname, ".."),
});
assert(false); // Should never reach this
} catch (e) {
err = (e as Error).message
.replaceAll("✘", "X")
.replace(/\\/g, "/")
.replace(/[^\S\n]+\n/g, "\n")
.trimEnd();
}
expect(err).toMatchInlineSnapshot(`
"Command failed: pnpm run dev
X [ERROR] Your Worker depends on the following Durable Objects, which are not exported in your entrypoint file: FooBar.
You should export these objects from your entrypoint, src/index.js."
`);
});
});
7 changes: 7 additions & 0 deletions fixtures/durable-objects-app/tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@cloudflare/workers-tsconfig/tsconfig.json",
"compilerOptions": {
"types": ["node"]
},
"include": ["**/*.ts", "../../../node-types.d.ts"]
}
12 changes: 12 additions & 0 deletions fixtures/durable-objects-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2020",
"esModuleInterop": true,
"module": "CommonJS",
"lib": ["ES2020"],
"types": ["node"],
"moduleResolution": "node",
"noEmit": true
},
"include": ["tests", "../../node-types.d.ts"]
}
13 changes: 13 additions & 0 deletions fixtures/durable-objects-app/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name = "do-worker-app"
compatibility_date = "2022-03-31"

main = "src/index.js"

[durable_objects]
bindings = [
{ name = "MY_DO", class_name = "FooBar" }
]

[[migrations]]
tag = "v1"
new_classes = ["FooBar"]
10 changes: 9 additions & 1 deletion packages/wrangler/src/__tests__/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7654,7 +7654,15 @@ export default{
},
migrations: [{ tag: "v1", new_classes: ["SomeClass"] }],
});
writeWorkerSource();
fs.writeFileSync(
"index.js",
`export default {
async fetch(request) {
return new Response('Hello' + foo);
},
};
export class SomeClass {};`
);
process.env.CLOUDFLARE_ACCOUNT_ID = "";
await runWrangler("deploy index.js --dry-run");
expect(std).toMatchInlineSnapshot(`
Expand Down
12 changes: 12 additions & 0 deletions packages/wrangler/src/deployment-bundle/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,18 @@ export async function bundleWorker(
}

const entryPoint = getEntryPointFromMetafile(entryFile, result.metafile);
const notExportedDOs = doBindings
.filter((x) => !x.script_name && !entryPoint.exports.includes(x.class_name))
.map((x) => x.class_name);
if (notExportedDOs.length) {
const relativePath = path.relative(process.cwd(), entryFile);
throw new Error(
`Your Worker depends on the following Durable Objects, which are not exported in your entrypoint file: ${notExportedDOs.join(
", "
)}.\nYou should export these objects from your entrypoint, ${relativePath}.`
);
}

const bundleType = entryPoint.exports.length > 0 ? "esm" : "commonjs";

const sourceMapPath = Object.keys(result.metafile.outputs).filter((_path) =>
Expand Down
134 changes: 78 additions & 56 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6c8f41f

Please sign in to comment.