|
1 | 1 | import { TRPCError } from "@trpc/server"; |
| 2 | +import { getHTTPStatusCodeFromError } from "@trpc/server/http"; |
2 | 3 | import { createMiddleware } from "hono/factory"; |
3 | 4 | import { HTTPException } from "hono/http-exception"; |
4 | 5 |
|
5 | | -function trpcCodeToHttpCode(code: TRPCError["code"]) { |
6 | | - switch (code) { |
7 | | - case "BAD_REQUEST": |
8 | | - case "PARSE_ERROR": |
9 | | - return 400; |
10 | | - case "UNAUTHORIZED": |
11 | | - return 401; |
12 | | - case "FORBIDDEN": |
13 | | - return 403; |
14 | | - case "NOT_FOUND": |
15 | | - return 404; |
16 | | - case "METHOD_NOT_SUPPORTED": |
17 | | - return 405; |
18 | | - case "TIMEOUT": |
19 | | - return 408; |
20 | | - case "PAYLOAD_TOO_LARGE": |
21 | | - return 413; |
22 | | - case "TOO_MANY_REQUESTS": |
23 | | - return 429; |
24 | | - case "INTERNAL_SERVER_ERROR": |
25 | | - return 500; |
26 | | - default: |
27 | | - return 500; |
28 | | - } |
| 6 | +import type { ContentfulStatusCode } from "hono/utils/http-status"; |
| 7 | + |
| 8 | +// trpc maps CLIENT_CLOSED_REQUEST to 499, which isn't part of hono's status |
| 9 | +// code union; everything else it emits is a standard contentful 4xx/5xx. |
| 10 | +function isContentfulStatusCode( |
| 11 | + status: number, |
| 12 | +): status is ContentfulStatusCode { |
| 13 | + return status >= 400 && status <= 511 && status !== 499; |
29 | 14 | } |
30 | 15 |
|
31 | 16 | const trpcAdapter = createMiddleware(async (c, next) => { |
32 | 17 | await next(); |
33 | 18 | const e = c.error; |
34 | 19 | if (e instanceof TRPCError) { |
35 | | - const code = trpcCodeToHttpCode(e.code); |
| 20 | + const status = getHTTPStatusCodeFromError(e); |
36 | 21 | const isInternalError = e.code === "INTERNAL_SERVER_ERROR"; |
37 | 22 | const isProd = process.env.NODE_ENV === "production"; |
38 | | - throw new HTTPException(code, { |
| 23 | + throw new HTTPException(isContentfulStatusCode(status) ? status : 500, { |
39 | 24 | message: isInternalError && isProd ? "Internal server error" : e.message, |
40 | 25 | cause: isInternalError && isProd ? undefined : e.cause, |
41 | 26 | }); |
|
0 commit comments