Skip to content

Commit b193b22

Browse files
authored
fix: update for more recent deno versions (#44)
1 parent 2a9f572 commit b193b22

File tree

3 files changed

+61
-30
lines changed

3 files changed

+61
-30
lines changed

deno-bootstrap/index.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ const socketFile = Deno.args[0];
22
const scriptType = Deno.args[1];
33
const script = Deno.args[2];
44

5-
const importURL =
6-
scriptType === "import"
7-
? script
8-
: `data:text/tsx,${encodeURIComponent(script)}`;
5+
const importURL = scriptType === "import"
6+
? script
7+
: `data:text/tsx,${encodeURIComponent(script)}`;
98

109
const mod = await import(importURL);
1110
if (!mod.default) {
@@ -15,8 +14,7 @@ if (typeof mod.default.fetch !== "function") {
1514
throw new Error("Default export does not have a fetch function.");
1615
}
1716

18-
const onError =
19-
mod.default.onError ??
17+
const onError = mod.default.onError ??
2018
((error: unknown) => {
2119
console.error(error);
2220
return new Response("Internal Server Error", { status: 500 });
@@ -44,25 +42,32 @@ const server = Deno.serve(
4442
// Restore host and connection headers.
4543
req.headers.delete("host");
4644
req.headers.delete("connection");
47-
if (req.headers.has("X-Deno-Worker-Host"))
45+
if (req.headers.has("X-Deno-Worker-Host")) {
4846
req.headers.set("host", req.headers.get("X-Deno-Worker-Host")!);
49-
if (req.headers.has("X-Deno-Worker-Connection"))
47+
}
48+
if (req.headers.has("X-Deno-Worker-Connection")) {
5049
req.headers.set(
5150
"connection",
52-
req.headers.get("X-Deno-Worker-Connection")!
51+
req.headers.get("X-Deno-Worker-Connection")!,
5352
);
53+
}
5454

5555
req.headers.delete("X-Deno-Worker-URL");
5656
req.headers.delete("X-Deno-Worker-Host");
5757
req.headers.delete("X-Deno-Worker-Connection");
5858
return mod.default.fetch(req);
59-
}
59+
},
6060
);
6161

62-
globalThis.onerror = (e) => {
62+
addEventListener("error", (e) => {
6363
console.error(e.error);
6464
e.preventDefault();
65-
};
65+
});
66+
67+
addEventListener("unhandledrejection", (e) => {
68+
console.error(e.reason);
69+
e.preventDefault();
70+
});
6671

6772
Deno.addSignalListener("SIGINT", async () => {
6873
// On interrupt we only shut down the server. Deno will wait for all

src/DenoHTTPWorker.test.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => {
103103
worker.terminate();
104104
});
105105

106-
it("dont crash on socket removal", async () => {
106+
it("don't crash on socket removal", async () => {
107107
const worker = await newDenoHTTPWorker(
108108
`
109109
export default { async fetch (req: Request): Promise<Response> {
@@ -170,21 +170,44 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => {
170170

171171
worker.terminate();
172172
});
173+
173174
it("onError not handled", { timeout: 20_000 }, async () => {
174-
// onError is not called in all cases, for example, here I can pass a
175-
// readable stream and the error is only caught by the global onerror handler.
175+
// onError is not called for errors that happen outside the request
176176
const worker = await newDenoHTTPWorker(
177177
`
178178
export default { async fetch (req: Request): Promise<Response> {
179-
const body = new ReadableStream({
180-
start(controller) {
181-
setTimeout(() => {
182-
controller.enqueue(1);
183-
}, 10);
184-
},
185-
cancel() {},
186-
});
187-
return new Response(body)
179+
setTimeout(() => {
180+
throw new Error("uncaught!")
181+
})
182+
return Response.json(null)
183+
}, onError (error: Error): Response {
184+
return Response.json({ error: error.message }, { status: 500 })
185+
}}
186+
`,
187+
{ printOutput: false }
188+
);
189+
jsonRequest(worker, "https://localhost/hello?isee=you", {
190+
headers: { accept: "application/json" },
191+
}).catch(() => {});
192+
193+
for (;;) {
194+
const stderr = worker.stderr.read();
195+
if (stderr) {
196+
expect(stderr.toString()).toContain("Error: uncaught!");
197+
break;
198+
}
199+
await new Promise((resolve) => setTimeout(resolve, 100));
200+
}
201+
worker.terminate();
202+
});
203+
204+
it("unhandled rejection", { timeout: 20_000 }, async () => {
205+
// onError is not called for unhandled rejections that happen outside the request
206+
const worker = await newDenoHTTPWorker(
207+
`
208+
export default { async fetch (req: Request): Promise<Response> {
209+
Promise.reject(new Error("uncaught!"))
210+
return Response.json(null)
188211
}, onError (error: Error): Response {
189212
return Response.json({ error: error.message }, { status: 500 })
190213
}}
@@ -198,8 +221,7 @@ describe("DenoHTTPWorker", { timeout: 1000 }, () => {
198221
for (;;) {
199222
const stderr = worker.stderr.read();
200223
if (stderr) {
201-
console.log(stderr.toString());
202-
expect(stderr.toString()).toContain("expected typed ArrayBufferView");
224+
expect(stderr.toString()).toContain("Error: uncaught!");
203225
break;
204226
}
205227
await new Promise((resolve) => setTimeout(resolve, 100));

src/DenoHTTPWorker.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export const newDenoHTTPWorker = async (
138138
const allowReadFlagValue =
139139
typeof script === "string"
140140
? socketFile
141-
: `${socketFile},${script.href.replace("file://", "")}`;
141+
: `${socketFile},${fileURLToPath(script)}`;
142142

143143
let allowReadFound = false;
144144
let allowWriteFound = false;
@@ -182,6 +182,8 @@ export const newDenoHTTPWorker = async (
182182
? _options.denoExecutable
183183
: (_options.denoExecutable[0] as string);
184184

185+
const bootstrap = await fs.readFile(_options.denoBootstrapScriptPath, "utf-8");
186+
185187
return new Promise((resolve, reject) => {
186188
(async (): Promise<DenoHTTPWorker> => {
187189
const args = [
@@ -190,7 +192,7 @@ export const newDenoHTTPWorker = async (
190192
: _options.denoExecutable.slice(1)),
191193
"run",
192194
..._options.runFlags,
193-
_options.denoBootstrapScriptPath,
195+
"data:text/typescript," + encodeURIComponent(bootstrap),
194196
...scriptArgs,
195197
];
196198
if (_options.printCommandAndArguments) {
@@ -351,10 +353,12 @@ class denoHTTPWorker {
351353
// (https://nodejs.org/api/http.html#new-agentoptions). We don't want these
352354
// to make it to Deno unless they are explicitly set by the user. So store
353355
// them to reconstruct on the other size.
354-
if (options.headers.host)
356+
if (options.headers.host) {
355357
options.headers["X-Deno-Worker-Host"] = options.headers.host;
356-
if (options.headers.connection)
358+
}
359+
if (options.headers.connection) {
357360
options.headers["X-Deno-Worker-Connection"] = options.headers.connection;
361+
}
358362

359363
options.headers = {
360364
...options.headers,

0 commit comments

Comments
 (0)