Skip to content

Commit d75f36b

Browse files
authored
Merge pull request #108 from stainless-api/sam/fix-hono-plugin
fix(hono): return 204 for void handler results instead of crashing
2 parents 524b879 + 3fa2af2 commit d75f36b

5 files changed

Lines changed: 60 additions & 12 deletions

File tree

packages/hono/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"typescript": "^5.3.2"
3535
},
3636
"dependencies": {
37-
"hono": "^4.0.0",
37+
"hono": "^4.12.1",
3838
"qs": "^6.11.2",
3939
"stainless": "workspace:*"
4040
}

packages/hono/src/__tests__/honoPlugin.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,50 @@ import { stlApi } from "../honoPlugin";
44

55
const stl = new Stl({ plugins: {} });
66

7+
describe("void-returning handlers", () => {
8+
const api = stl.api({
9+
basePath: "/api",
10+
resources: {
11+
webhooks: stl.resource({
12+
summary: "webhooks",
13+
actions: {
14+
fireAndForget: stl.endpoint({
15+
endpoint: "POST /api/webhooks/events",
16+
handler: async () => {
17+
// Handler that does work but returns nothing
18+
},
19+
}),
20+
earlyReturn: stl.endpoint({
21+
endpoint: "POST /api/webhooks/noop",
22+
handler: async () => {
23+
return;
24+
},
25+
}),
26+
},
27+
}),
28+
},
29+
});
30+
31+
const app = new Hono();
32+
app.use("*", stlApi(api));
33+
34+
test("handler returning void responds with 204", async () => {
35+
const response = await app.request("/api/webhooks/events", {
36+
method: "POST",
37+
});
38+
expect(response.status).toBe(204);
39+
expect(await response.text()).toBe("");
40+
});
41+
42+
test("handler with explicit bare return responds with 204", async () => {
43+
const response = await app.request("/api/webhooks/noop", {
44+
method: "POST",
45+
});
46+
expect(response.status).toBe(204);
47+
expect(await response.text()).toBe("");
48+
});
49+
});
50+
751
describe("basic routing", () => {
852
const api = stl.api({
953
basePath: "/api",

packages/hono/src/honoPlugin.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Context } from "hono";
22
import { createMiddleware } from "hono/factory";
3-
import { StatusCode } from "hono/utils/http-status";
3+
import { ContentfulStatusCode } from "hono/utils/http-status";
44
import qs from "qs";
55
import {
66
allEndpoints,
@@ -91,14 +91,18 @@ function makeHandler(endpoints: AnyEndpoint[], options?: StlAppOptions) {
9191
return result;
9292
}
9393

94+
if (result === undefined) {
95+
return c.body(null, 204);
96+
}
97+
9498
return c.json(result);
9599
} catch (error) {
96100
if (options?.handleErrors === false) {
97101
throw error;
98102
}
99103

100104
if (isStlError(error)) {
101-
return c.json(error.response, error.statusCode as StatusCode);
105+
return c.json(error.response, error.statusCode as ContentfulStatusCode);
102106
}
103107

104108
console.error(

packages/next/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"next": "^14.2.8"
3232
},
3333
"dependencies": {
34-
"hono": "^4.0.0",
34+
"hono": "^4.12.0",
3535
"lodash": "^4.17.21",
3636
"qs": "^6.11.2",
3737
"stainless": "workspace:*"

pnpm-lock.yaml

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)