@nxtedition/logger 1.0.2 → 1.0.3
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/package.json +3 -3
- package/dist/index.js +0 -2
- package/dist/logger.js +0 -83
- package/dist/platform.js +0 -38
- package/dist/serializers.js +0 -353
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/logger",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "UNLICENSED",
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build": "rimraf dist &&
|
|
15
|
+
"build": "rimraf dist && tsc",
|
|
16
16
|
"prepublishOnly": "yarn build",
|
|
17
17
|
"typecheck": "tsc --noEmit",
|
|
18
18
|
"test": "node --test",
|
|
@@ -23,5 +23,5 @@
|
|
|
23
23
|
"pino": "^10.3.1",
|
|
24
24
|
"request-target": "^1.0.2"
|
|
25
25
|
},
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "fd0bcacdf9e7b58fb2a540e0529c6b4961c2b0b5"
|
|
27
27
|
}
|
package/dist/index.js
DELETED
package/dist/logger.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { isMainThread } from 'node:worker_threads'
|
|
2
|
-
import serializers from './serializers.js'
|
|
3
|
-
import pino from 'pino'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const isProduction = process.env.NODE_ENV === 'production'
|
|
15
|
-
|
|
16
|
-
export function createLogger(
|
|
17
|
-
{
|
|
18
|
-
level = isProduction ? 'debug' : 'trace',
|
|
19
|
-
flushInterval = 1e3,
|
|
20
|
-
stream,
|
|
21
|
-
...options
|
|
22
|
-
} = {},
|
|
23
|
-
onTerminate ,
|
|
24
|
-
) {
|
|
25
|
-
if (!stream) {
|
|
26
|
-
if (
|
|
27
|
-
process.stdout.write !== process.stdout.constructor.prototype.write ||
|
|
28
|
-
process.stdout.fd == null
|
|
29
|
-
) {
|
|
30
|
-
stream = pino.destination(process.stdout)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (stream) {
|
|
35
|
-
// Do nothing...
|
|
36
|
-
} else if (!isProduction) {
|
|
37
|
-
stream = pino.destination({ fd: process.stdout.fd ?? 1, sync: true, fsync: false })
|
|
38
|
-
} else if (!isMainThread) {
|
|
39
|
-
// TODO (perf): Async mode doesn't work super well in workers.
|
|
40
|
-
stream = pino.destination({ fd: 1, sync: true, fsync: false })
|
|
41
|
-
} else {
|
|
42
|
-
stream = pino.destination({
|
|
43
|
-
sync: false,
|
|
44
|
-
fsync: false,
|
|
45
|
-
minLength: 4 * 1024,
|
|
46
|
-
maxWrite: 32 * 1024,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
let flushing = 0
|
|
50
|
-
const onFlush = () => {
|
|
51
|
-
flushing--
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const flushTimeout = setInterval(() => {
|
|
55
|
-
if (flushing >= 10) {
|
|
56
|
-
try {
|
|
57
|
-
logger.warn('logger is flushing too slow')
|
|
58
|
-
stream?.flushSync()
|
|
59
|
-
} catch (err) {
|
|
60
|
-
console.error(err)
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
flushing++
|
|
64
|
-
stream?.flush(onFlush)
|
|
65
|
-
}
|
|
66
|
-
flushTimeout.refresh()
|
|
67
|
-
}, flushInterval).unref()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const logger = pino(
|
|
71
|
-
{
|
|
72
|
-
level,
|
|
73
|
-
...options,
|
|
74
|
-
serializers: {
|
|
75
|
-
...serializers,
|
|
76
|
-
...options.serializers,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
stream,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
return logger
|
|
83
|
-
}
|
package/dist/platform.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export const SIGNALS =
|
|
2
|
-
typeof process === 'object'
|
|
3
|
-
? process.platform === 'linux'
|
|
4
|
-
? {
|
|
5
|
-
129: 'SIGHUP', // 1
|
|
6
|
-
130: 'SIGINT', // 2
|
|
7
|
-
131: 'SIGQUIT', // 3
|
|
8
|
-
132: 'SIGILL', // 4
|
|
9
|
-
133: 'SIGTRAP', // 5
|
|
10
|
-
134: 'SIGABRT', // 6
|
|
11
|
-
135: 'SIGBUS', // 7
|
|
12
|
-
136: 'SIGFPE', // 8
|
|
13
|
-
137: 'SIGKILL', // 9
|
|
14
|
-
138: 'SIGUSR1', // 10
|
|
15
|
-
139: 'SIGSEGV', // 11
|
|
16
|
-
140: 'SIGUSR2', // 12
|
|
17
|
-
141: 'SIGPIPE', // 13
|
|
18
|
-
142: 'SIGALRM', // 14
|
|
19
|
-
143: 'SIGTERM', // 15
|
|
20
|
-
144: 'SIGSTKFLT', // 16
|
|
21
|
-
145: 'SIGCHLD', // 17
|
|
22
|
-
146: 'SIGCONT', // 18
|
|
23
|
-
147: 'SIGSTOP', // 19
|
|
24
|
-
148: 'SIGTSTP', // 20
|
|
25
|
-
149: 'SIGTTIN', // 21
|
|
26
|
-
150: 'SIGTTOU', // 22
|
|
27
|
-
151: 'SIGURG', // 23
|
|
28
|
-
152: 'SIGXCPU', // 24
|
|
29
|
-
153: 'SIGXFSZ', // 25
|
|
30
|
-
154: 'SIGVTALRM', // 26
|
|
31
|
-
155: 'SIGPROF', // 27
|
|
32
|
-
156: 'SIGWINCH', // 28
|
|
33
|
-
157: 'SIGIO', // 29
|
|
34
|
-
158: 'SIGPWR', // 30
|
|
35
|
-
159: 'SIGSYS', // 31
|
|
36
|
-
}
|
|
37
|
-
: {}
|
|
38
|
-
: {}
|
package/dist/serializers.js
DELETED
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import { SIGNALS } from './platform.ts'
|
|
2
|
-
import { parseHeaders } from '@nxtedition/nxt-undici'
|
|
3
|
-
import requestTarget from 'request-target'
|
|
4
|
-
import querystring from 'fast-querystring'
|
|
5
|
-
|
|
6
|
-
function getHeader(obj, key) {
|
|
7
|
-
return !obj || !key
|
|
8
|
-
? undefined
|
|
9
|
-
: obj.headers?.[key] || obj.headers?.get?.(key) || obj.getHeader?.(key)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getHeaders(obj) {
|
|
13
|
-
if (!obj) {
|
|
14
|
-
return undefined
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (obj.getHeaders) {
|
|
18
|
-
return obj.getHeaders()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (obj.headers) {
|
|
22
|
-
return Array.isArray(obj.headers) ? parseHeaders(obj.headers) : obj.headers
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (obj.headers?.entries) {
|
|
26
|
-
return Object.fromEntries(obj.headers.entries())
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return undefined
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getUrl(obj) {
|
|
33
|
-
if (!obj) {
|
|
34
|
-
return undefined
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const { origin, path, hostname, protocol, port, url } = obj
|
|
38
|
-
|
|
39
|
-
if (typeof url === 'string' && url) {
|
|
40
|
-
return url
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const href = url?.href
|
|
44
|
-
if (typeof href === 'string' && href) {
|
|
45
|
-
return href
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (origin && (!path || typeof path === 'string')) {
|
|
49
|
-
if (typeof origin === 'object') {
|
|
50
|
-
return `${origin.protocol || 'http:'}//${origin.hostname}:${origin.port || { 'http:': 80, 'https:': 443 }[origin.protocol]}${path || ''}`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (typeof origin === 'string') {
|
|
54
|
-
if (path?.startsWith('/') && origin.endsWith('/')) {
|
|
55
|
-
return `${origin.slice(0, -1)}${path || ''}`
|
|
56
|
-
} else {
|
|
57
|
-
return `${origin}${path || ''}`
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (typeof hostname === 'string') {
|
|
63
|
-
return `${protocol || 'http:'}//${hostname}:${port || { 'http:': 80, 'https:': 443 }[protocol || 'http:']}${path || ''}`
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (typeof path === 'string' && path) {
|
|
67
|
-
return path
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return null
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function getTarget(obj) {
|
|
74
|
-
if (!obj) {
|
|
75
|
-
return undefined
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
if (obj.target) {
|
|
80
|
-
return obj.target
|
|
81
|
-
}
|
|
82
|
-
if (typeof obj.url === 'string') {
|
|
83
|
-
return requestTarget(
|
|
84
|
-
obj.headers ? obj : { url: obj.url, headers: obj.headers ?? {}, socket: obj.socket },
|
|
85
|
-
)
|
|
86
|
-
} else {
|
|
87
|
-
const { origin, path, hostname, protocol, port, search, query } = obj
|
|
88
|
-
return {
|
|
89
|
-
origin,
|
|
90
|
-
protocol: protocol || undefined,
|
|
91
|
-
hostname: hostname || undefined,
|
|
92
|
-
port: port || undefined,
|
|
93
|
-
pathname: path || undefined,
|
|
94
|
-
search:
|
|
95
|
-
search ||
|
|
96
|
-
(typeof query === 'object' && query != null ? querystring.stringify(query) : undefined),
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
} catch {
|
|
100
|
-
return undefined
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// TODO(fix): What if url is instanceof URL?
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export default {
|
|
107
|
-
err: (err) => errSerializer(err),
|
|
108
|
-
error: (err) => errSerializer(err),
|
|
109
|
-
errors: (err) => errSerializer(err),
|
|
110
|
-
socket: (socket) =>
|
|
111
|
-
socket && {
|
|
112
|
-
id: socket.id || undefined,
|
|
113
|
-
version: socket.version || undefined,
|
|
114
|
-
user: socket.user || undefined,
|
|
115
|
-
userAgent: socket.userAgent || undefined,
|
|
116
|
-
remoteAddress: socket.remoteAddress || undefined,
|
|
117
|
-
headers: socket.headers,
|
|
118
|
-
},
|
|
119
|
-
req: (req) =>
|
|
120
|
-
req && {
|
|
121
|
-
id: req.id || getHeader(req, 'request-id'),
|
|
122
|
-
httpVersion: req.httpVersion,
|
|
123
|
-
method: req.method,
|
|
124
|
-
target: getTarget(req),
|
|
125
|
-
url: getUrl(req),
|
|
126
|
-
headers: getHeaders(req),
|
|
127
|
-
timing: req.timing,
|
|
128
|
-
bytesRead: req.bytesRead >= 0 ? req.bytesRead : undefined,
|
|
129
|
-
bytesReadPerSecond:
|
|
130
|
-
req.bytesReadPerSecond ??
|
|
131
|
-
(req.timing?.end > 0 && req.bytesRead > 0
|
|
132
|
-
? (req.bytesRead * 1e3) / req.timing.end
|
|
133
|
-
: undefined),
|
|
134
|
-
remoteAddress: req.socket?.remoteAddress,
|
|
135
|
-
remotePort: req.socket?.remotePort,
|
|
136
|
-
aborted: req.aborted,
|
|
137
|
-
closed: req.closed,
|
|
138
|
-
destroyed: req.destroyed,
|
|
139
|
-
},
|
|
140
|
-
ureq: (ureq) =>
|
|
141
|
-
ureq && {
|
|
142
|
-
id: ureq.id || getHeader(ureq, 'request-id'),
|
|
143
|
-
httpVersion: ureq.httpVersion,
|
|
144
|
-
method: ureq.method,
|
|
145
|
-
target: getTarget(ureq),
|
|
146
|
-
url: getUrl(ureq),
|
|
147
|
-
headers: getHeaders(ureq),
|
|
148
|
-
timing: ureq.timing,
|
|
149
|
-
bytesWritten: ureq.bytesWritten,
|
|
150
|
-
bytesReadPerSecond:
|
|
151
|
-
ureq.bytesWrittenPerSecond ??
|
|
152
|
-
(ureq.timing && ureq.timing.data > 0 && ureq.timing.end > 0
|
|
153
|
-
? (ureq.bytesWritten * 1e3) / (ureq.timing.end - ureq.timing.data)
|
|
154
|
-
: undefined),
|
|
155
|
-
body: typeof ureq.body === 'string' ? ureq.body : undefined,
|
|
156
|
-
},
|
|
157
|
-
res: (res) =>
|
|
158
|
-
res && {
|
|
159
|
-
id: res.id || getHeader(res, 'request-id') || getHeader(res.req, 'request-id'),
|
|
160
|
-
httpVersion: res.httpVersion,
|
|
161
|
-
headers: getHeaders(res),
|
|
162
|
-
statusCode: res.statusCode || res.status,
|
|
163
|
-
timing: res.timing,
|
|
164
|
-
bytesWritten: res.bytesWritten >= 0 ? res.bytesWritten : undefined,
|
|
165
|
-
bytesWrittenPerSecond:
|
|
166
|
-
res.bytesWrittenPerSecond ??
|
|
167
|
-
(res.timing?.end > 0 && res.bytesWritten > 0
|
|
168
|
-
? (res.bytesWritten * 1e3) / res.timing.end
|
|
169
|
-
: undefined),
|
|
170
|
-
headersSent: res.headersSent,
|
|
171
|
-
aborted: res.aborted,
|
|
172
|
-
closed: res.closed,
|
|
173
|
-
destroyed: res.destroyed,
|
|
174
|
-
},
|
|
175
|
-
ures: (ures) =>
|
|
176
|
-
ures && {
|
|
177
|
-
id: ures.id || getHeader(ures, 'request-id') || getHeader(ures.req, 'request-id'),
|
|
178
|
-
httpVersion: ures.httpVersion,
|
|
179
|
-
headers: getHeaders(ures),
|
|
180
|
-
statusCode: ures.statusCode ?? ures.status,
|
|
181
|
-
timing: ures.timing,
|
|
182
|
-
bytesRead: ures.bytesRead,
|
|
183
|
-
bytesReadPerSecond:
|
|
184
|
-
ures.bytesReadPerSecond ??
|
|
185
|
-
(ures.timing && ures.timing.data > 0 && ures.timing.end > 0
|
|
186
|
-
? (ures.bytesRead * 1e3) / (ures.timing.end - ures.timing.data)
|
|
187
|
-
: undefined),
|
|
188
|
-
body: typeof ures.body === 'string' ? ures.body : undefined,
|
|
189
|
-
},
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// TODO (fix): Merge with errros/serializeError.
|
|
193
|
-
// Note that 'data' here should be string while in "serializeError" it should be object.
|
|
194
|
-
// Maybe we should rename serializeError to makeErrorObject or somehting??
|
|
195
|
-
|
|
196
|
-
// Based on: https://github.com/pinojs/pino-std-serializers
|
|
197
|
-
|
|
198
|
-
const seen = Symbol('circular-ref-tag')
|
|
199
|
-
export const rawSymbol = Symbol('pino-raw-err-ref')
|
|
200
|
-
|
|
201
|
-
const pinoErrProto = Object.create(
|
|
202
|
-
{},
|
|
203
|
-
{
|
|
204
|
-
type: {
|
|
205
|
-
enumerable: true,
|
|
206
|
-
writable: true,
|
|
207
|
-
value: undefined,
|
|
208
|
-
},
|
|
209
|
-
message: {
|
|
210
|
-
enumerable: true,
|
|
211
|
-
writable: true,
|
|
212
|
-
value: undefined,
|
|
213
|
-
},
|
|
214
|
-
stack: {
|
|
215
|
-
enumerable: true,
|
|
216
|
-
writable: true,
|
|
217
|
-
value: undefined,
|
|
218
|
-
},
|
|
219
|
-
errors: {
|
|
220
|
-
enumerable: true,
|
|
221
|
-
writable: true,
|
|
222
|
-
value: undefined,
|
|
223
|
-
},
|
|
224
|
-
raw: {
|
|
225
|
-
enumerable: false,
|
|
226
|
-
get: function () {
|
|
227
|
-
return this[rawSymbol]
|
|
228
|
-
},
|
|
229
|
-
set: function (val) {
|
|
230
|
-
this[rawSymbol] = val
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
)
|
|
235
|
-
Object.defineProperty(pinoErrProto, rawSymbol, {
|
|
236
|
-
writable: true,
|
|
237
|
-
value: {},
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
function errSerializer(err) {
|
|
241
|
-
if (Array.isArray(err)) {
|
|
242
|
-
return err.length === 0 ? undefined : errSerializer({ message: '', errors: err })
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (!isErrorLike(err)) {
|
|
246
|
-
return undefined
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const errors = Array.isArray(err?.errors)
|
|
250
|
-
? err.errors.map((err) => errSerializer(err)).filter(Boolean)
|
|
251
|
-
: null
|
|
252
|
-
|
|
253
|
-
if (err.message === '' && errors != null && errors.length === 0) {
|
|
254
|
-
return undefined
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (err.message === '' && errors != null && errors.length === 1) {
|
|
258
|
-
return errSerializer(err.errors[0])
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
err[seen] = undefined // tag to prevent re-looking at this
|
|
262
|
-
const _err = Object.create(pinoErrProto)
|
|
263
|
-
_err.type =
|
|
264
|
-
Object.prototype.toString.call(err.constructor) === '[object Function]'
|
|
265
|
-
? err.constructor.name
|
|
266
|
-
: err.name
|
|
267
|
-
_err.name = err.name
|
|
268
|
-
_err.message = err.message
|
|
269
|
-
_err.stack = err.stack
|
|
270
|
-
|
|
271
|
-
if (errors != null) {
|
|
272
|
-
_err.errors = errors
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (isErrorLike(err.cause) && !Object.prototype.hasOwnProperty.call(err.cause, seen)) {
|
|
276
|
-
_err.cause = errSerializer(err.cause)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
for (const key in err) {
|
|
280
|
-
if (_err[key] === undefined) {
|
|
281
|
-
const val = err[key]
|
|
282
|
-
if (isErrorLike(val)) {
|
|
283
|
-
if (!Object.prototype.hasOwnProperty.call(val, seen)) {
|
|
284
|
-
_err[key] = errSerializer(val)
|
|
285
|
-
}
|
|
286
|
-
} else if (typeof val === 'bigint') {
|
|
287
|
-
_err[key] = `${val.toString()}`
|
|
288
|
-
} else if (val != null && !/^[A-Z0-9_]+$/.test(key)) {
|
|
289
|
-
_err[key] = val
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (_err.data != null && typeof _err.data !== 'string') {
|
|
295
|
-
try {
|
|
296
|
-
_err.data = JSON.stringify(_err.data, (k, v) => (typeof v === 'bigint' ? v.toString() : v), 2)
|
|
297
|
-
} catch {
|
|
298
|
-
// Do nothing...
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (_err.body != null && typeof _err.body !== 'string') {
|
|
303
|
-
try {
|
|
304
|
-
_err.body = JSON.stringify(_err.body, (k, v) => (typeof v === 'bigint' ? v.toString() : v), 2)
|
|
305
|
-
} catch {
|
|
306
|
-
// Do nothing...
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (_err.meta != null && typeof _err.meta !== 'string') {
|
|
311
|
-
try {
|
|
312
|
-
_err.meta = JSON.stringify(_err.meta, (k, v) => (typeof v === 'bigint' ? v.toString() : v), 2)
|
|
313
|
-
} catch {
|
|
314
|
-
// Do nothing...
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (_err.code != null && typeof _err.code !== 'string') {
|
|
319
|
-
_err.code = String(_err.code)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (_err.emitter != null && typeof _err.emitter === 'object') {
|
|
323
|
-
_err.emitter = undefined
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (_err.statusCode == null && _err.status != null) {
|
|
327
|
-
_err.statusCode = Number(_err.status) || undefined
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (_err.signalCode == null && _err.signal != null) {
|
|
331
|
-
_err.signalCode = SIGNALS[_err._signal] ?? _err._signal
|
|
332
|
-
} else if (_err.signalCode != null) {
|
|
333
|
-
_err.signalCode = SIGNALS[_err.signalCode] ?? _err.signalCode
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
if (_err.exitCode == null && _err.code != null && /^([A-Z]+|[a-z]+|[0-9]+)$/.test(_err.code)) {
|
|
337
|
-
_err.exitCode = String(_err.code)
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
delete err[seen] // clean up tag in case err is serialized again later
|
|
341
|
-
_err.raw = err
|
|
342
|
-
return _err
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const isErrorLike = (err) => {
|
|
346
|
-
return (
|
|
347
|
-
err &&
|
|
348
|
-
(typeof err.message === 'string' ||
|
|
349
|
-
typeof err.status === 'number' ||
|
|
350
|
-
typeof err.statusCode === 'number' ||
|
|
351
|
-
typeof err.code === 'string')
|
|
352
|
-
)
|
|
353
|
-
}
|