1
1
import type { Context } from "hono"
2
+ import type { HTTPException } from "hono/http-exception"
3
+ import type { StatusCode } from "hono/utils/http-status"
2
4
import type { JSONSchema7 } from "json-schema"
3
5
import type { TypeOf , ZodError , z } from "zod"
4
6
@@ -15,6 +17,114 @@ export const mergeSchemas = <One extends JSONSchema7, Two extends JSONSchema7>(
15
17
} ,
16
18
} )
17
19
20
+ type ErrorJson = {
21
+ code ?: string
22
+ statusCode : number
23
+ error : string
24
+ message ?: string
25
+ }
26
+
27
+ const getErrorText = ( code : StatusCode ) => {
28
+ switch ( code ) {
29
+ case 400 :
30
+ return "Bad Request"
31
+ case 401 :
32
+ return "Unauthorized"
33
+ case 403 :
34
+ return "Forbidden"
35
+ case 404 :
36
+ return "Not Found"
37
+ case 405 :
38
+ return "Method Not Allowed"
39
+ case 406 :
40
+ return "Not Acceptable"
41
+ case 408 :
42
+ return "Request Timeout"
43
+ case 409 :
44
+ return "Conflict"
45
+ case 410 :
46
+ return "Gone"
47
+ case 411 :
48
+ return "Length Required"
49
+ case 412 :
50
+ return "Precondition Failed"
51
+ case 413 :
52
+ return "Payload Too Large"
53
+ case 414 :
54
+ return "URI Too Long"
55
+ case 415 :
56
+ return "Unsupported Media Type"
57
+ case 416 :
58
+ return "Range Not Satisfiable"
59
+ case 417 :
60
+ return "Expectation Failed"
61
+ case 418 :
62
+ return "I'm a teapot"
63
+ case 421 :
64
+ return "Misdirected Request"
65
+ case 422 :
66
+ return "Unprocessable Entity"
67
+ case 423 :
68
+ return "Locked"
69
+ case 424 :
70
+ return "Failed Dependency"
71
+ case 425 :
72
+ return "Too Early"
73
+ case 426 :
74
+ return "Upgrade Required"
75
+ case 428 :
76
+ return "Precondition Required"
77
+ case 429 :
78
+ return "Too Many Requests"
79
+ case 431 :
80
+ return "Request Header Fields Too Large"
81
+ case 451 :
82
+ return "Unavailable For Legal Reasons"
83
+ case 500 :
84
+ return "Internal Server Error"
85
+ case 501 :
86
+ return "Not Implemented"
87
+ case 502 :
88
+ return "Bad Gateway"
89
+ case 503 :
90
+ return "Service Unavailable"
91
+ case 504 :
92
+ return "Gateway Timeout"
93
+ case 505 :
94
+ return "HTTP Version Not Supported"
95
+ case 506 :
96
+ return "Variant Also Negotiates"
97
+ case 507 :
98
+ return "Insufficient Storage"
99
+ case 508 :
100
+ return "Loop Detected"
101
+ case 510 :
102
+ return "Not Extended"
103
+ case 511 :
104
+ return "Network Authentication Required"
105
+ default :
106
+ return "Error"
107
+ }
108
+ }
109
+
110
+ export const createErrorJson = ( c : Context , input : Pick < HTTPException , "status" | "message" > & { code ?: string } ) => {
111
+ const status : StatusCode = input . status
112
+ const body : Omit < ErrorJson , "error" | "statusCode" > = {
113
+ message : input . message ?? "An error occurred." ,
114
+ }
115
+
116
+ if ( input . code != null ) {
117
+ body . code = input . code
118
+ }
119
+
120
+ c . status ( status )
121
+ return c . json ( {
122
+ ...body ,
123
+ statusCode : status ,
124
+ error : getErrorText ( status ) ,
125
+ } )
126
+ }
127
+
18
128
export const zHook = < T extends z . ZodType < any , z . ZodTypeDef , any > > ( result : TypeOf < T > , c : Context ) => {
19
129
if ( result . success === true ) return
20
130
@@ -24,12 +134,10 @@ export const zHook = <T extends z.ZodType<any, z.ZodTypeDef, any>>(result: TypeO
24
134
...Object . entries ( flat . fieldErrors ) . map ( ( [ key , value ] ) => `${ key } : ${ value ?. join ( ", " ) ?? "error" } ` ) ,
25
135
]
26
136
27
- c . status ( 400 )
28
- return c . json ( {
29
- code : "FST_ERR_VALIDATION" ,
30
- error : "Bad Request" ,
31
- statusCode : 400 ,
137
+ return createErrorJson ( c , {
138
+ status : 400 ,
32
139
message : messages . join ( ", " ) ,
140
+ code : "FST_ERR_VALIDATION" ,
33
141
} )
34
142
}
35
143
0 commit comments