1 |
|
2 |
|
3 | const {
|
4 | kReplyIsError,
|
5 | kReplyHijacked
|
6 | } = require('./symbols')
|
7 |
|
8 | function wrapThenable (thenable, reply) {
|
9 | thenable.then(function (payload) {
|
10 | if (reply[kReplyHijacked] === true) {
|
11 | return
|
12 | }
|
13 |
|
14 | // this is for async functions that are using reply.send directly
|
15 | //
|
16 | // since wrap-thenable will be called when using reply.send directly
|
17 | // without actual return. the response can be sent already or
|
18 | // the request may be terminated during the reply. in this situation,
|
19 | // it require an extra checking of request.aborted to see whether
|
20 | // the request is killed by client.
|
21 | if (payload !== undefined || (reply.sent === false && reply.raw.headersSent === false && reply.request.raw.aborted === false)) {
|
22 | // we use a try-catch internally to avoid adding a catch to another
|
23 | // promise, increase promise perf by 10%
|
24 | try {
|
25 | reply.send(payload)
|
26 | } catch (err) {
|
27 | reply[kReplyIsError] = true
|
28 | reply.send(err)
|
29 | }
|
30 | }
|
31 | }, function (err) {
|
32 | if (reply.sent === true) {
|
33 | reply.log.error({ err }, 'Promise errored, but reply.sent = true was set')
|
34 | return
|
35 | }
|
36 |
|
37 | reply[kReplyIsError] = true
|
38 |
|
39 | // try-catch allow to re-throw error in error handler for async handler
|
40 | try {
|
41 | reply.send(err)
|
42 | // The following should not happen
|
43 | /* c8 ignore next 3 */
|
44 | } catch (err) {
|
45 | reply.send(err)
|
46 | }
|
47 | })
|
48 | }
|
49 |
|
50 | module.exports = wrapThenable
|