@nxtedition/lib 15.0.53 → 15.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/http.js +43 -39
- package/package.json +9 -9
package/http.js
CHANGED
|
@@ -2,7 +2,6 @@ const createError = require('http-errors')
|
|
|
2
2
|
const { performance } = require('perf_hooks')
|
|
3
3
|
const requestTarget = require('request-target')
|
|
4
4
|
const querystring = require('fast-querystring')
|
|
5
|
-
const assert = require('assert')
|
|
6
5
|
const compose = require('koa-compose')
|
|
7
6
|
const http = require('http')
|
|
8
7
|
const fp = require('lodash/fp')
|
|
@@ -24,6 +23,30 @@ function genReqId() {
|
|
|
24
23
|
return `req-${nextReqId.toString(36)}`
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
const kResolve = Symbol('resolve')
|
|
27
|
+
|
|
28
|
+
function onTimeout() {
|
|
29
|
+
this.destroy(new createError.RequestTimeout())
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function onRequestError(err) {
|
|
33
|
+
this.log.error({ err }, 'request error')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function onRequestClose() {
|
|
37
|
+
this.log.debug('request closed')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function onResponseError(err) {
|
|
41
|
+
this.log.error({ err }, 'response error')
|
|
42
|
+
this[kResolve](Promise.reject(err))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function onResponseClose() {
|
|
46
|
+
this.log.debug('response closed')
|
|
47
|
+
this[kResolve](null)
|
|
48
|
+
}
|
|
49
|
+
|
|
27
50
|
module.exports.request = async function request(ctx, next) {
|
|
28
51
|
const { req, res, logger } = ctx
|
|
29
52
|
const startTime = performance.now()
|
|
@@ -39,10 +62,10 @@ module.exports.request = async function request(ctx, next) {
|
|
|
39
62
|
}
|
|
40
63
|
|
|
41
64
|
ctx.id = req.id = req.headers['request-id'] || genReqId()
|
|
42
|
-
ctx.logger = req.log = logger.child({ req })
|
|
65
|
+
ctx.logger = req.log = res.log = logger.child({ req })
|
|
43
66
|
ctx.signal = signal
|
|
44
67
|
ctx.method = req.method
|
|
45
|
-
ctx.query = ctx.url.search ? querystring.parse(ctx.url.search.slice(1)) : {}
|
|
68
|
+
ctx.query = ctx.url.search.length > 1 ? querystring.parse(ctx.url.search.slice(1)) : {}
|
|
46
69
|
|
|
47
70
|
if (req.method === 'GET' || req.method === 'HEAD') {
|
|
48
71
|
req.resume() // Dump the body if there is one.
|
|
@@ -54,55 +77,34 @@ module.exports.request = async function request(ctx, next) {
|
|
|
54
77
|
|
|
55
78
|
reqLogger = ctx.logger
|
|
56
79
|
if (!isHealthcheck) {
|
|
57
|
-
reqLogger.debug(
|
|
80
|
+
reqLogger.debug('request started')
|
|
58
81
|
} else {
|
|
59
|
-
reqLogger.trace(
|
|
82
|
+
reqLogger.trace('request started')
|
|
60
83
|
}
|
|
61
84
|
|
|
62
85
|
await Promise.all([
|
|
63
86
|
next(),
|
|
64
|
-
new Promise((resolve
|
|
65
|
-
res
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
reqLogger.error({ err }, 'response error')
|
|
71
|
-
reject(err)
|
|
72
|
-
})
|
|
73
|
-
.on('close', function () {
|
|
74
|
-
reqLogger.debug('response closed')
|
|
75
|
-
resolve(null)
|
|
76
|
-
})
|
|
77
|
-
req
|
|
78
|
-
.on('timeout', function () {
|
|
79
|
-
this.destroy(new createError.RequestTimeout())
|
|
80
|
-
})
|
|
81
|
-
.on('error', function (err) {
|
|
82
|
-
reqLogger.error({ err }, 'request error')
|
|
83
|
-
})
|
|
84
|
-
.on('close', function () {
|
|
85
|
-
reqLogger.debug('request closed')
|
|
86
|
-
})
|
|
87
|
+
new Promise((resolve) => {
|
|
88
|
+
res[kResolve] = resolve
|
|
89
|
+
|
|
90
|
+
res.on('timeout', onTimeout).on('error', onResponseError).on('close', onResponseClose)
|
|
91
|
+
|
|
92
|
+
req.on('timeout', onTimeout).on('error', onRequestError).on('close', onRequestClose)
|
|
87
93
|
}),
|
|
88
94
|
])
|
|
89
95
|
|
|
90
|
-
assert(req.aborted || res.writableEnded)
|
|
91
|
-
|
|
92
96
|
const responseTime = Math.round(performance.now() - startTime)
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (req.aborted) {
|
|
97
|
-
reqLogger.debug('request aborted')
|
|
98
|
+
if (!res.writableEnded) {
|
|
99
|
+
reqLogger.debug({ res, responseTime }, 'request aborted')
|
|
98
100
|
} else if (res.statusCode >= 500) {
|
|
99
|
-
reqLogger.error('request error')
|
|
101
|
+
reqLogger.error({ res, responseTime }, 'request error')
|
|
100
102
|
} else if (res.statusCode >= 400) {
|
|
101
|
-
reqLogger.warn('request failed')
|
|
103
|
+
reqLogger.warn({ res, responseTime }, 'request failed')
|
|
102
104
|
} else if (!isHealthcheck) {
|
|
103
|
-
reqLogger.debug('request completed')
|
|
105
|
+
reqLogger.debug({ res, responseTime }, 'request completed')
|
|
104
106
|
} else {
|
|
105
|
-
reqLogger.trace('request completed')
|
|
107
|
+
reqLogger.trace({ res, responseTime }, 'request completed')
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
ac.abort()
|
|
@@ -162,7 +164,7 @@ module.exports.request = async function request(ctx, next) {
|
|
|
162
164
|
} else {
|
|
163
165
|
reqLogger = reqLogger.child({ res, err, reason, responseTime })
|
|
164
166
|
|
|
165
|
-
if (req.aborted || err.name === 'AbortError') {
|
|
167
|
+
if (req.aborted || !res.writableEnded || err.name === 'AbortError') {
|
|
166
168
|
reqLogger.debug('request aborted')
|
|
167
169
|
} else if (err.statusCode < 500) {
|
|
168
170
|
reqLogger.warn('request failed')
|
|
@@ -179,6 +181,8 @@ module.exports.request = async function request(ctx, next) {
|
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
ac.abort(err)
|
|
184
|
+
} finally {
|
|
185
|
+
res.destroy()
|
|
182
186
|
}
|
|
183
187
|
}
|
|
184
188
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/lib",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.55",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"files": [
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"lodash": "^4.17.21",
|
|
82
82
|
"mime": "^3.0.0",
|
|
83
83
|
"moment-timezone": "^0.5.43",
|
|
84
|
-
"nconf": "^0.12.
|
|
84
|
+
"nconf": "^0.12.1",
|
|
85
85
|
"nested-error-stacks": "^2.1.1",
|
|
86
86
|
"object-hash": "^3.0.0",
|
|
87
87
|
"pino-std-serializers": "^6.2.2",
|
|
@@ -90,25 +90,25 @@
|
|
|
90
90
|
"smpte-timecode": "^1.3.3",
|
|
91
91
|
"split-string": "^6.0.0",
|
|
92
92
|
"toobusy-js": "^0.5.1",
|
|
93
|
-
"undici": "^5.
|
|
93
|
+
"undici": "^5.27.1",
|
|
94
94
|
"url-join": "^4.0.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@types/node": "^20.8.
|
|
98
|
-
"eslint": "^8.
|
|
97
|
+
"@types/node": "^20.8.10",
|
|
98
|
+
"eslint": "^8.52.0",
|
|
99
99
|
"eslint-config-prettier": "^9.0.0",
|
|
100
100
|
"eslint-config-standard": "^17.0.0",
|
|
101
|
-
"eslint-plugin-import": "^2.
|
|
102
|
-
"eslint-plugin-n": "^16.
|
|
101
|
+
"eslint-plugin-import": "^2.29.0",
|
|
102
|
+
"eslint-plugin-n": "^16.2.0",
|
|
103
103
|
"eslint-plugin-node": "^11.1.0",
|
|
104
104
|
"eslint-plugin-promise": "^6.0.0",
|
|
105
105
|
"husky": "^8.0.3",
|
|
106
|
-
"lint-staged": "^
|
|
106
|
+
"lint-staged": "^15.0.2",
|
|
107
107
|
"pinst": "^3.0.0",
|
|
108
108
|
"prettier": "^3.0.3",
|
|
109
109
|
"rxjs": "^7.5.6",
|
|
110
110
|
"send": "^0.18.0",
|
|
111
|
-
"tap": "^18.
|
|
111
|
+
"tap": "^18.5.6"
|
|
112
112
|
},
|
|
113
113
|
"peerDependencies": {
|
|
114
114
|
"@elastic/elasticsearch": "^8.6.0",
|