@@ -18,13 +18,28 @@ class ErrorHandler {
18
18
this . links = Array . isArray ( links ) ? links : [ links ]
19
19
}
20
20
21
+ /**
22
+ * Creates Google and Stack Overflow links
23
+ * which allow the user to search for
24
+ * help on these platforms.
25
+ *
26
+ * @returns {Array }
27
+ */
21
28
defaultLinks ( ) {
22
29
return [
23
30
( error ) => this . google ( error ) ,
24
31
( error ) => this . stackOverflow ( error )
25
32
]
26
33
}
27
34
35
+ /**
36
+ * Resolve a Google link with
37
+ * the error’s message.
38
+ *
39
+ * @param {Object } error
40
+ *
41
+ * @returns {String }
42
+ */
28
43
google ( error ) {
29
44
return `
30
45
<a
@@ -35,6 +50,14 @@ class ErrorHandler {
35
50
</a>`
36
51
}
37
52
53
+ /**
54
+ * Resolve a Stack Overflow link
55
+ * with the error’s message.
56
+ *
57
+ * @param {Object } error
58
+ *
59
+ * @returns {String }
60
+ */
38
61
stackOverflow ( error ) {
39
62
return `
40
63
<a
@@ -45,14 +68,38 @@ class ErrorHandler {
45
68
</a>`
46
69
}
47
70
71
+ /**
72
+ * Read the icon from disk.
73
+ *
74
+ * @param {String } name
75
+ *
76
+ * @returns {String }
77
+ */
48
78
resolveIcon ( name ) {
49
79
return Fs . readFileSync ( this . resolveIconPath ( name ) )
50
80
}
51
81
82
+ /**
83
+ * Resolve the icon’s path on the disk.
84
+ *
85
+ * @param {String } name
86
+ *
87
+ * @returns {String }
88
+ */
52
89
resolveIconPath ( name ) {
53
90
return Path . resolve ( __dirname , 'icons' , `${ name } .svg` )
54
91
}
55
92
93
+ /**
94
+ * Check the outgoing response whether it’s
95
+ * a developer error. If yes, show the
96
+ * error details view.
97
+ *
98
+ * @param {Request } request
99
+ * @param {Toolkit } h
100
+ *
101
+ * @returns {Response }
102
+ */
56
103
async handle ( request , h ) {
57
104
if ( this . isDeveloperError ( request . response ) ) {
58
105
return this . resolveError ( request , h )
@@ -61,10 +108,25 @@ class ErrorHandler {
61
108
return h . continue
62
109
}
63
110
111
+ /**
112
+ * Check whether the `error` is a 500 error
113
+ *
114
+ * @param {Object } error
115
+ *
116
+ * @returns {Boolean }
117
+ */
64
118
isDeveloperError ( error ) {
65
119
return error . isBoom && error . output . statusCode === 500
66
120
}
67
121
122
+ /**
123
+ * Resolve the error and format, JSON or HTML.
124
+ *
125
+ * @param {Request } request
126
+ * @param {Toolkit } h
127
+ *
128
+ * @returns {Response }
129
+ */
68
130
async resolveError ( request , h ) {
69
131
await this . logToTerminal ( request )
70
132
@@ -79,6 +141,11 @@ class ErrorHandler {
79
141
return this . sendHtml ( request , h )
80
142
}
81
143
144
+ /**
145
+ * Logs the error to terminal.
146
+ *
147
+ * @param {Request } request
148
+ */
82
149
async logToTerminal ( request ) {
83
150
if ( this . toTerminal ) {
84
151
const youch = this . createYouch ( request )
@@ -88,6 +155,15 @@ class ErrorHandler {
88
155
}
89
156
}
90
157
158
+ /**
159
+ * Create a Youch instance to render a
160
+ * detailed error view or serialize
161
+ * the error to JSON.
162
+ *
163
+ * @param {Request } request
164
+ *
165
+ * @returns {Object }
166
+ */
91
167
createYouch ( request ) {
92
168
const error = request . response
93
169
error . status = error . output . statusCode
@@ -104,16 +180,40 @@ class ErrorHandler {
104
180
}
105
181
}
106
182
183
+ /**
184
+ * Determines whether the request
185
+ * expects JSON in response.
186
+ *
187
+ * @param {Request } request
188
+ *
189
+ * @returns {Boolean }
190
+ */
107
191
wantsJson ( request ) {
108
192
const { 'user-agent' : agent , accept } = request . raw . req . headers
109
193
110
194
return this . matches ( agent , / c u r l | w g e t | p o s t m a n | i n s o m n i a / i) || this . matches ( accept , / j s o n / )
111
195
}
112
196
197
+ /**
198
+ * Determine whether the given `str`
199
+ * matches the `regex`.
200
+ *
201
+ * @param {String } str
202
+ * @param {String } regex
203
+ *
204
+ * @returns {Boolean }
205
+ */
113
206
matches ( str , regex ) {
114
207
return str && str . match ( regex )
115
208
}
116
209
210
+ /**
211
+ * Create an error object.
212
+ *
213
+ * @param {Request } request
214
+ *
215
+ * @returns {Object }
216
+ */
117
217
composeError ( request ) {
118
218
const error = request . response
119
219
@@ -129,6 +229,14 @@ class ErrorHandler {
129
229
}
130
230
}
131
231
232
+ /**
233
+ * Respond the request with JSON.
234
+ *
235
+ * @param {Request } request
236
+ * @param {Toolkit } h
237
+ *
238
+ * @returns {Response }
239
+ */
132
240
sendJson ( request , h ) {
133
241
const error = this . composeError ( request )
134
242
const json = this . resolveJson ( error )
@@ -139,17 +247,39 @@ class ErrorHandler {
139
247
. code ( error . statusCode )
140
248
}
141
249
250
+ /**
251
+ * JSON.stringify the error object and
252
+ * prettify the stackstrace.
253
+ *
254
+ * @param {Object } data
255
+ *
256
+ * @returns {String }
257
+ */
142
258
resolveJson ( data ) {
143
259
return JSON . stringify ( {
144
260
...data ,
145
261
stacktrace : data . stacktrace . split ( '\n' ) . map ( line => line . trim ( ) )
146
262
} )
147
263
}
148
264
265
+ /**
266
+ * Determine whether the user wants to
267
+ * render their own template.
268
+ *
269
+ * @returns {Boolean }
270
+ */
149
271
hasTemplate ( ) {
150
272
return ! ! this . template
151
273
}
152
274
275
+ /**
276
+ * Render the defined user template.
277
+ *
278
+ * @param {Request } request
279
+ * @param {Toolkit } h
280
+ *
281
+ * @returns {Response }
282
+ */
153
283
renderTemplate ( request , h ) {
154
284
const error = this . composeError ( request )
155
285
@@ -158,6 +288,14 @@ class ErrorHandler {
158
288
. code ( error . statusCode )
159
289
}
160
290
291
+ /**
292
+ * Respond the request with HTML.
293
+ *
294
+ * @param {Request } request
295
+ * @param {Toolkit } h
296
+ *
297
+ * @returns {Response }
298
+ */
161
299
async sendHtml ( request , h ) {
162
300
const youch = this . createYouch ( request )
163
301
const statusCode = request . response . output . statusCode
0 commit comments