Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 389b13f

Browse files
committed
Add clear error if Durable Object missing fetch handler, closes #164
1 parent 4eb120b commit 389b13f

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

packages/durable-objects/src/error.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export type DurableObjectErrorCode =
44
| "ERR_SCRIPT_NOT_FOUND" // Missing mounted script for object
55
| "ERR_CLASS_NOT_FOUND" // Missing constructor for object
66
| "ERR_RESPONSE_TYPE" // Fetch handler returned non-Response object;
7-
| "ERR_DESERIALIZATION"; // Unable to deserialize stored value (likely loading data created in Miniflare 1)
7+
| "ERR_DESERIALIZATION" // Unable to deserialize stored value (likely loading data created in Miniflare 1)
8+
| "ERR_NO_HANDLER"; // No fetch handler for object
89

910
export class DurableObjectError extends MiniflareError<DurableObjectErrorCode> {}

packages/durable-objects/src/namespace.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,16 @@ export class DurableObjectState {
8282
// TODO: catch, reset object on error
8383
const outputGate = new OutputGate();
8484
return outputGate.runWith(() =>
85-
this.#inputGate.runWith(() => this[kInstance]!.fetch(request))
85+
this.#inputGate.runWith(() => {
86+
const instance = this[kInstance];
87+
if (!instance?.fetch) {
88+
throw new DurableObjectError(
89+
"ERR_NO_HANDLER",
90+
"No fetch handler defined in Durable Object"
91+
);
92+
}
93+
return instance.fetch(request);
94+
})
8695
);
8796
}
8897
}

packages/durable-objects/test/namespace.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,25 @@ test("DurableObjectState: kFetch: waits for writes to be confirmed before return
147147
assert(value);
148148
t.is(deserialize(value), "value");
149149
});
150+
test("DurableObjectState: kFetch: throws clear error if missing fetch handler", async (t) => {
151+
// https://github.com/cloudflare/miniflare/issues/164
152+
const factory = new MemoryStorageFactory();
153+
const plugin = new DurableObjectsPlugin(ctx, {
154+
durableObjects: { TEST: "TestObject" },
155+
});
156+
157+
class TestObject {}
158+
plugin.beforeReload();
159+
plugin.reload({}, { TestObject }, new Map());
160+
161+
const ns = plugin.getNamespace(factory, "TEST");
162+
const id = ns.newUniqueId();
163+
await t.throwsAsync(ns.get(id).fetch("http://localhost"), {
164+
instanceOf: DurableObjectError,
165+
code: "ERR_NO_HANDLER",
166+
message: "No fetch handler defined in Durable Object",
167+
});
168+
});
150169
test("DurableObjectState: hides implementation details", async (t) => {
151170
const [ns, plugin, factory] = getTestObjectNamespace();
152171
const state = await plugin.getObject(factory, ns.newUniqueId());

0 commit comments

Comments
 (0)