Skip to content

Commit fb2e248

Browse files
committed
fix: improve node middleware handling
1 parent 632952b commit fb2e248

File tree

3 files changed

+39
-22
lines changed

3 files changed

+39
-22
lines changed

src/adapters.ts

+16-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
} from "./types";
99
import { toNodeHandler as _toNodeHandler } from "srvx/node";
1010
import { createError } from "./error";
11+
import { kHandled } from "./response";
1112

1213
export function toWebHandler(
1314
app: H3,
@@ -72,23 +73,24 @@ function callNodeHandler(
7273
) {
7374
const isMiddleware = handler.length > 2;
7475
return new Promise((resolve, reject) => {
75-
const next = (err?: Error) => {
76-
if (isMiddleware) {
77-
res.off("close", next);
78-
res.off("error", next);
79-
}
80-
return err ? reject(createError(err)) : resolve(undefined);
81-
};
76+
res.once("close", () => resolve(kHandled));
77+
res.once("finish", () => resolve(kHandled));
78+
res.once("pipe", () => resolve(kHandled));
79+
res.once("error", (error) => reject(error));
8280
try {
83-
const returned = handler(req, res, next);
84-
if (isMiddleware && returned === undefined) {
85-
res.once("close", next);
86-
res.once("error", next);
81+
if (isMiddleware) {
82+
Promise.resolve(
83+
handler(req, res, (err) =>
84+
err ? reject(createError(err)) : resolve(void 0),
85+
),
86+
).catch((error) => reject(createError(error)));
8787
} else {
88-
resolve(returned);
88+
return Promise.resolve((handler as NodeHandler)(req, res))
89+
.then(() => resolve(kHandled))
90+
.catch((error) => reject(createError(error)));
8991
}
90-
} catch (error) {
91-
next(error as Error);
92+
} catch (error: any) {
93+
reject(createError(error));
9294
}
9395
});
9496
}

src/response.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createError } from "./error";
66
import { isJSONSerializable } from "./utils/internal/object";
77

88
export const kNotFound = /* @__PURE__ */ Symbol.for("h3.notFound");
9+
export const kHandled = /* @__PURE__ */ Symbol.for("h3.handled");
910

1011
export function prepareResponse(
1112
val: unknown,
@@ -14,6 +15,10 @@ export function prepareResponse(
1415
): Response {
1516
const isHead = event.method === "HEAD";
1617

18+
if (val === kHandled) {
19+
return new Response(null);
20+
}
21+
1722
if (val instanceof Response) {
1823
const we = event as H3WebEvent;
1924
const status = we.response.status;

test/integrations.test.ts

+18-8
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,14 @@ describeMatrix("integrations", (t, { it, expect, describe }) => {
5757
t.app.use(
5858
"/api/hello",
5959
fromNodeHandler(
60-
defineNodeHandler((req, res) => ({
61-
url: req.url,
62-
prop: (res as any).prop,
63-
})),
60+
defineNodeHandler((req, res) => {
61+
res.end(
62+
JSON.stringify({
63+
url: req.url,
64+
prop: (res as any).prop,
65+
}),
66+
);
67+
}),
6468
),
6569
);
6670
expressApp.use("/api", toNodeHandler(t.app) as any);
@@ -93,10 +97,16 @@ describeMatrix("integrations", (t, { it, expect, describe }) => {
9397
);
9498
t.app.use(
9599
"/api/hello",
96-
fromNodeHandler((req, res) => ({
97-
url: req.url,
98-
prop: (res as any).prop,
99-
})),
100+
fromNodeHandler(
101+
defineNodeHandler((req, res) => {
102+
res.end(
103+
JSON.stringify({
104+
url: req.url,
105+
prop: (res as any).prop,
106+
}),
107+
);
108+
}),
109+
),
100110
);
101111
connectApp.use("/api", toNodeHandler(t.app));
102112

0 commit comments

Comments
 (0)