deepv-code 1.0.182 → 1.0.185
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/bundle/dvcode.js +757 -753
- package/package.json +1 -1
- package/bundle/assets/help/README.md +0 -113
- package/bundle/assets/sounds/README.md +0 -74
- package/bundle/node_modules/undici/LICENSE +0 -21
- package/bundle/node_modules/undici/README.md +0 -472
- package/bundle/node_modules/undici/docs/docs/api/Agent.md +0 -83
- package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
- package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
- package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +0 -151
- package/bundle/node_modules/undici/docs/docs/api/Client.md +0 -281
- package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
- package/bundle/node_modules/undici/docs/docs/api/Connector.md +0 -115
- package/bundle/node_modules/undici/docs/docs/api/ContentType.md +0 -57
- package/bundle/node_modules/undici/docs/docs/api/Cookies.md +0 -101
- package/bundle/node_modules/undici/docs/docs/api/Debug.md +0 -62
- package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -204
- package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1200
- package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
- package/bundle/node_modules/undici/docs/docs/api/Errors.md +0 -49
- package/bundle/node_modules/undici/docs/docs/api/EventSource.md +0 -45
- package/bundle/node_modules/undici/docs/docs/api/Fetch.md +0 -52
- package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +0 -262
- package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
- package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
- package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
- package/bundle/node_modules/undici/docs/docs/api/MockClient.md +0 -77
- package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
- package/bundle/node_modules/undici/docs/docs/api/MockPool.md +0 -548
- package/bundle/node_modules/undici/docs/docs/api/Pool.md +0 -84
- package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
- package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -227
- package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -96
- package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +0 -45
- package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +0 -117
- package/bundle/node_modules/undici/docs/docs/api/Util.md +0 -25
- package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +0 -85
- package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
- package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
- package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
- package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
- package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -20
- package/bundle/node_modules/undici/index-fetch.js +0 -35
- package/bundle/node_modules/undici/index.d.ts +0 -3
- package/bundle/node_modules/undici/index.js +0 -183
- package/bundle/node_modules/undici/lib/api/abort-signal.js +0 -59
- package/bundle/node_modules/undici/lib/api/api-connect.js +0 -110
- package/bundle/node_modules/undici/lib/api/api-pipeline.js +0 -252
- package/bundle/node_modules/undici/lib/api/api-request.js +0 -199
- package/bundle/node_modules/undici/lib/api/api-stream.js +0 -209
- package/bundle/node_modules/undici/lib/api/api-upgrade.js +0 -110
- package/bundle/node_modules/undici/lib/api/index.js +0 -7
- package/bundle/node_modules/undici/lib/api/readable.js +0 -558
- package/bundle/node_modules/undici/lib/api/util.js +0 -95
- package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
- package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
- package/bundle/node_modules/undici/lib/core/connect.js +0 -164
- package/bundle/node_modules/undici/lib/core/constants.js +0 -143
- package/bundle/node_modules/undici/lib/core/diagnostics.js +0 -196
- package/bundle/node_modules/undici/lib/core/errors.js +0 -244
- package/bundle/node_modules/undici/lib/core/request.js +0 -397
- package/bundle/node_modules/undici/lib/core/symbols.js +0 -68
- package/bundle/node_modules/undici/lib/core/tree.js +0 -160
- package/bundle/node_modules/undici/lib/core/util.js +0 -988
- package/bundle/node_modules/undici/lib/dispatcher/agent.js +0 -135
- package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -206
- package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +0 -1615
- package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +0 -798
- package/bundle/node_modules/undici/lib/dispatcher/client.js +0 -614
- package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -161
- package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
- package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -151
- package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -159
- package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +0 -122
- package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +0 -191
- package/bundle/node_modules/undici/lib/dispatcher/pool.js +0 -118
- package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -275
- package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
- package/bundle/node_modules/undici/lib/global.js +0 -32
- package/bundle/node_modules/undici/lib/handler/cache-handler.js +0 -448
- package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
- package/bundle/node_modules/undici/lib/handler/decorator-handler.js +0 -67
- package/bundle/node_modules/undici/lib/handler/redirect-handler.js +0 -227
- package/bundle/node_modules/undici/lib/handler/retry-handler.js +0 -342
- package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +0 -96
- package/bundle/node_modules/undici/lib/handler/wrap-handler.js +0 -95
- package/bundle/node_modules/undici/lib/interceptor/cache.js +0 -372
- package/bundle/node_modules/undici/lib/interceptor/dns.js +0 -432
- package/bundle/node_modules/undici/lib/interceptor/dump.js +0 -111
- package/bundle/node_modules/undici/lib/interceptor/redirect.js +0 -21
- package/bundle/node_modules/undici/lib/interceptor/response-error.js +0 -95
- package/bundle/node_modules/undici/lib/interceptor/retry.js +0 -19
- package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +0 -97
- package/bundle/node_modules/undici/lib/llhttp/constants.js +0 -498
- package/bundle/node_modules/undici/lib/llhttp/constants.js.map +0 -1
- package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
- package/bundle/node_modules/undici/lib/llhttp/utils.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/utils.js.map +0 -1
- package/bundle/node_modules/undici/lib/mock/mock-agent.js +0 -224
- package/bundle/node_modules/undici/lib/mock/mock-call-history.js +0 -248
- package/bundle/node_modules/undici/lib/mock/mock-client.js +0 -64
- package/bundle/node_modules/undici/lib/mock/mock-errors.js +0 -19
- package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
- package/bundle/node_modules/undici/lib/mock/mock-pool.js +0 -64
- package/bundle/node_modules/undici/lib/mock/mock-symbols.js +0 -31
- package/bundle/node_modules/undici/lib/mock/mock-utils.js +0 -433
- package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
- package/bundle/node_modules/undici/lib/util/cache.js +0 -368
- package/bundle/node_modules/undici/lib/util/date.js +0 -259
- package/bundle/node_modules/undici/lib/util/stats.js +0 -32
- package/bundle/node_modules/undici/lib/util/timers.js +0 -423
- package/bundle/node_modules/undici/lib/web/cache/cache.js +0 -862
- package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
- package/bundle/node_modules/undici/lib/web/cache/util.js +0 -45
- package/bundle/node_modules/undici/lib/web/cookies/constants.js +0 -12
- package/bundle/node_modules/undici/lib/web/cookies/index.js +0 -199
- package/bundle/node_modules/undici/lib/web/cookies/parse.js +0 -322
- package/bundle/node_modules/undici/lib/web/cookies/util.js +0 -282
- package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
- package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +0 -484
- package/bundle/node_modules/undici/lib/web/eventsource/util.js +0 -37
- package/bundle/node_modules/undici/lib/web/fetch/LICENSE +0 -21
- package/bundle/node_modules/undici/lib/web/fetch/body.js +0 -532
- package/bundle/node_modules/undici/lib/web/fetch/constants.js +0 -131
- package/bundle/node_modules/undici/lib/web/fetch/data-url.js +0 -744
- package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +0 -46
- package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -501
- package/bundle/node_modules/undici/lib/web/fetch/formdata.js +0 -263
- package/bundle/node_modules/undici/lib/web/fetch/global.js +0 -40
- package/bundle/node_modules/undici/lib/web/fetch/headers.js +0 -719
- package/bundle/node_modules/undici/lib/web/fetch/index.js +0 -2258
- package/bundle/node_modules/undici/lib/web/fetch/request.js +0 -1099
- package/bundle/node_modules/undici/lib/web/fetch/response.js +0 -636
- package/bundle/node_modules/undici/lib/web/fetch/util.js +0 -1782
- package/bundle/node_modules/undici/lib/web/fetch/webidl.js +0 -740
- package/bundle/node_modules/undici/lib/web/websocket/connection.js +0 -325
- package/bundle/node_modules/undici/lib/web/websocket/constants.js +0 -126
- package/bundle/node_modules/undici/lib/web/websocket/events.js +0 -331
- package/bundle/node_modules/undici/lib/web/websocket/frame.js +0 -138
- package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -70
- package/bundle/node_modules/undici/lib/web/websocket/receiver.js +0 -454
- package/bundle/node_modules/undici/lib/web/websocket/sender.js +0 -109
- package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -83
- package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -485
- package/bundle/node_modules/undici/lib/web/websocket/util.js +0 -338
- package/bundle/node_modules/undici/lib/web/websocket/websocket.js +0 -686
- package/bundle/node_modules/undici/package.json +0 -149
- package/bundle/node_modules/undici/scripts/strip-comments.js +0 -10
- package/bundle/node_modules/undici/types/README.md +0 -6
- package/bundle/node_modules/undici/types/agent.d.ts +0 -35
- package/bundle/node_modules/undici/types/api.d.ts +0 -43
- package/bundle/node_modules/undici/types/balanced-pool.d.ts +0 -29
- package/bundle/node_modules/undici/types/cache-interceptor.d.ts +0 -172
- package/bundle/node_modules/undici/types/cache.d.ts +0 -36
- package/bundle/node_modules/undici/types/client-stats.d.ts +0 -15
- package/bundle/node_modules/undici/types/client.d.ts +0 -110
- package/bundle/node_modules/undici/types/connector.d.ts +0 -34
- package/bundle/node_modules/undici/types/content-type.d.ts +0 -21
- package/bundle/node_modules/undici/types/cookies.d.ts +0 -30
- package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +0 -66
- package/bundle/node_modules/undici/types/dispatcher.d.ts +0 -281
- package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -21
- package/bundle/node_modules/undici/types/errors.d.ts +0 -171
- package/bundle/node_modules/undici/types/eventsource.d.ts +0 -61
- package/bundle/node_modules/undici/types/fetch.d.ts +0 -210
- package/bundle/node_modules/undici/types/formdata.d.ts +0 -108
- package/bundle/node_modules/undici/types/global-dispatcher.d.ts +0 -9
- package/bundle/node_modules/undici/types/global-origin.d.ts +0 -7
- package/bundle/node_modules/undici/types/h2c-client.d.ts +0 -75
- package/bundle/node_modules/undici/types/handlers.d.ts +0 -15
- package/bundle/node_modules/undici/types/header.d.ts +0 -160
- package/bundle/node_modules/undici/types/index.d.ts +0 -75
- package/bundle/node_modules/undici/types/interceptors.d.ts +0 -34
- package/bundle/node_modules/undici/types/mock-agent.d.ts +0 -68
- package/bundle/node_modules/undici/types/mock-call-history.d.ts +0 -111
- package/bundle/node_modules/undici/types/mock-client.d.ts +0 -25
- package/bundle/node_modules/undici/types/mock-errors.d.ts +0 -12
- package/bundle/node_modules/undici/types/mock-interceptor.d.ts +0 -93
- package/bundle/node_modules/undici/types/mock-pool.d.ts +0 -25
- package/bundle/node_modules/undici/types/patch.d.ts +0 -29
- package/bundle/node_modules/undici/types/pool-stats.d.ts +0 -19
- package/bundle/node_modules/undici/types/pool.d.ts +0 -41
- package/bundle/node_modules/undici/types/proxy-agent.d.ts +0 -29
- package/bundle/node_modules/undici/types/readable.d.ts +0 -68
- package/bundle/node_modules/undici/types/retry-agent.d.ts +0 -8
- package/bundle/node_modules/undici/types/retry-handler.d.ts +0 -116
- package/bundle/node_modules/undici/types/util.d.ts +0 -18
- package/bundle/node_modules/undici/types/utility.d.ts +0 -7
- package/bundle/node_modules/undici/types/webidl.d.ts +0 -266
- package/bundle/node_modules/undici/types/websocket.d.ts +0 -184
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const util = require('../core/util')
|
|
4
|
-
const { kBodyUsed } = require('../core/symbols')
|
|
5
|
-
const assert = require('node:assert')
|
|
6
|
-
const { InvalidArgumentError } = require('../core/errors')
|
|
7
|
-
const EE = require('node:events')
|
|
8
|
-
|
|
9
|
-
const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]
|
|
10
|
-
|
|
11
|
-
const kBody = Symbol('body')
|
|
12
|
-
|
|
13
|
-
const noop = () => {}
|
|
14
|
-
|
|
15
|
-
class BodyAsyncIterable {
|
|
16
|
-
constructor (body) {
|
|
17
|
-
this[kBody] = body
|
|
18
|
-
this[kBodyUsed] = false
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async * [Symbol.asyncIterator] () {
|
|
22
|
-
assert(!this[kBodyUsed], 'disturbed')
|
|
23
|
-
this[kBodyUsed] = true
|
|
24
|
-
yield * this[kBody]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
class RedirectHandler {
|
|
29
|
-
static buildDispatch (dispatcher, maxRedirections) {
|
|
30
|
-
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
|
|
31
|
-
throw new InvalidArgumentError('maxRedirections must be a positive number')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const dispatch = dispatcher.dispatch.bind(dispatcher)
|
|
35
|
-
return (opts, originalHandler) => dispatch(opts, new RedirectHandler(dispatch, maxRedirections, opts, originalHandler))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
constructor (dispatch, maxRedirections, opts, handler) {
|
|
39
|
-
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
|
|
40
|
-
throw new InvalidArgumentError('maxRedirections must be a positive number')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this.dispatch = dispatch
|
|
44
|
-
this.location = null
|
|
45
|
-
this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy
|
|
46
|
-
this.maxRedirections = maxRedirections
|
|
47
|
-
this.handler = handler
|
|
48
|
-
this.history = []
|
|
49
|
-
|
|
50
|
-
if (util.isStream(this.opts.body)) {
|
|
51
|
-
// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
|
|
52
|
-
// so that it can be dispatched again?
|
|
53
|
-
// TODO (fix): Do we need 100-expect support to provide a way to do this properly?
|
|
54
|
-
if (util.bodyLength(this.opts.body) === 0) {
|
|
55
|
-
this.opts.body
|
|
56
|
-
.on('data', function () {
|
|
57
|
-
assert(false)
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (typeof this.opts.body.readableDidRead !== 'boolean') {
|
|
62
|
-
this.opts.body[kBodyUsed] = false
|
|
63
|
-
EE.prototype.on.call(this.opts.body, 'data', function () {
|
|
64
|
-
this[kBodyUsed] = true
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
} else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') {
|
|
68
|
-
// TODO (fix): We can't access ReadableStream internal state
|
|
69
|
-
// to determine whether or not it has been disturbed. This is just
|
|
70
|
-
// a workaround.
|
|
71
|
-
this.opts.body = new BodyAsyncIterable(this.opts.body)
|
|
72
|
-
} else if (
|
|
73
|
-
this.opts.body &&
|
|
74
|
-
typeof this.opts.body !== 'string' &&
|
|
75
|
-
!ArrayBuffer.isView(this.opts.body) &&
|
|
76
|
-
util.isIterable(this.opts.body) &&
|
|
77
|
-
!util.isFormDataLike(this.opts.body)
|
|
78
|
-
) {
|
|
79
|
-
// TODO: Should we allow re-using iterable if !this.opts.idempotent
|
|
80
|
-
// or through some other flag?
|
|
81
|
-
this.opts.body = new BodyAsyncIterable(this.opts.body)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
onRequestStart (controller, context) {
|
|
86
|
-
this.handler.onRequestStart?.(controller, { ...context, history: this.history })
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
onRequestUpgrade (controller, statusCode, headers, socket) {
|
|
90
|
-
this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
94
|
-
if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) {
|
|
95
|
-
throw new Error('max redirects')
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// https://tools.ietf.org/html/rfc7231#section-6.4.2
|
|
99
|
-
// https://fetch.spec.whatwg.org/#http-redirect-fetch
|
|
100
|
-
// In case of HTTP 301 or 302 with POST, change the method to GET
|
|
101
|
-
if ((statusCode === 301 || statusCode === 302) && this.opts.method === 'POST') {
|
|
102
|
-
this.opts.method = 'GET'
|
|
103
|
-
if (util.isStream(this.opts.body)) {
|
|
104
|
-
util.destroy(this.opts.body.on('error', noop))
|
|
105
|
-
}
|
|
106
|
-
this.opts.body = null
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// https://tools.ietf.org/html/rfc7231#section-6.4.4
|
|
110
|
-
// In case of HTTP 303, always replace method to be either HEAD or GET
|
|
111
|
-
if (statusCode === 303 && this.opts.method !== 'HEAD') {
|
|
112
|
-
this.opts.method = 'GET'
|
|
113
|
-
if (util.isStream(this.opts.body)) {
|
|
114
|
-
util.destroy(this.opts.body.on('error', noop))
|
|
115
|
-
}
|
|
116
|
-
this.opts.body = null
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) || redirectableStatusCodes.indexOf(statusCode) === -1
|
|
120
|
-
? null
|
|
121
|
-
: headers.location
|
|
122
|
-
|
|
123
|
-
if (this.opts.origin) {
|
|
124
|
-
this.history.push(new URL(this.opts.path, this.opts.origin))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (!this.location) {
|
|
128
|
-
this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
|
|
133
|
-
const path = search ? `${pathname}${search}` : pathname
|
|
134
|
-
|
|
135
|
-
// Remove headers referring to the original URL.
|
|
136
|
-
// By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers.
|
|
137
|
-
// https://tools.ietf.org/html/rfc7231#section-6.4
|
|
138
|
-
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin)
|
|
139
|
-
this.opts.path = path
|
|
140
|
-
this.opts.origin = origin
|
|
141
|
-
this.opts.maxRedirections = 0
|
|
142
|
-
this.opts.query = null
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
onResponseData (controller, chunk) {
|
|
146
|
-
if (this.location) {
|
|
147
|
-
/*
|
|
148
|
-
https://tools.ietf.org/html/rfc7231#section-6.4
|
|
149
|
-
|
|
150
|
-
TLDR: undici always ignores 3xx response bodies.
|
|
151
|
-
|
|
152
|
-
Redirection is used to serve the requested resource from another URL, so it assumes that
|
|
153
|
-
no body is generated (and thus can be ignored). Even though generating a body is not prohibited.
|
|
154
|
-
|
|
155
|
-
For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually
|
|
156
|
-
(which means it's optional and not mandated) contain just an hyperlink to the value of
|
|
157
|
-
the Location response header, so the body can be ignored safely.
|
|
158
|
-
|
|
159
|
-
For status 300, which is "Multiple Choices", the spec mentions both generating a Location
|
|
160
|
-
response header AND a response body with the other possible location to follow.
|
|
161
|
-
Since the spec explicitly chooses not to specify a format for such body and leave it to
|
|
162
|
-
servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it.
|
|
163
|
-
*/
|
|
164
|
-
} else {
|
|
165
|
-
this.handler.onResponseData?.(controller, chunk)
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
onResponseEnd (controller, trailers) {
|
|
170
|
-
if (this.location) {
|
|
171
|
-
/*
|
|
172
|
-
https://tools.ietf.org/html/rfc7231#section-6.4
|
|
173
|
-
|
|
174
|
-
TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections
|
|
175
|
-
and neither are useful if present.
|
|
176
|
-
|
|
177
|
-
See comment on onData method above for more detailed information.
|
|
178
|
-
*/
|
|
179
|
-
this.dispatch(this.opts, this)
|
|
180
|
-
} else {
|
|
181
|
-
this.handler.onResponseEnd(controller, trailers)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
onResponseError (controller, error) {
|
|
186
|
-
this.handler.onResponseError?.(controller, error)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// https://tools.ietf.org/html/rfc7231#section-6.4.4
|
|
191
|
-
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
|
|
192
|
-
if (header.length === 4) {
|
|
193
|
-
return util.headerNameToString(header) === 'host'
|
|
194
|
-
}
|
|
195
|
-
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
|
|
196
|
-
return true
|
|
197
|
-
}
|
|
198
|
-
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
|
|
199
|
-
const name = util.headerNameToString(header)
|
|
200
|
-
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
|
|
201
|
-
}
|
|
202
|
-
return false
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// https://tools.ietf.org/html/rfc7231#section-6.4
|
|
206
|
-
function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
|
|
207
|
-
const ret = []
|
|
208
|
-
if (Array.isArray(headers)) {
|
|
209
|
-
for (let i = 0; i < headers.length; i += 2) {
|
|
210
|
-
if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) {
|
|
211
|
-
ret.push(headers[i], headers[i + 1])
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
} else if (headers && typeof headers === 'object') {
|
|
215
|
-
const entries = typeof headers[Symbol.iterator] === 'function' ? headers : Object.entries(headers)
|
|
216
|
-
for (const [key, value] of entries) {
|
|
217
|
-
if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) {
|
|
218
|
-
ret.push(key, value)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
assert(headers == null, 'headers must be an object or an array')
|
|
223
|
-
}
|
|
224
|
-
return ret
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
module.exports = RedirectHandler
|
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
const assert = require('node:assert')
|
|
3
|
-
|
|
4
|
-
const { kRetryHandlerDefaultRetry } = require('../core/symbols')
|
|
5
|
-
const { RequestRetryError } = require('../core/errors')
|
|
6
|
-
const WrapHandler = require('./wrap-handler')
|
|
7
|
-
const {
|
|
8
|
-
isDisturbed,
|
|
9
|
-
parseRangeHeader,
|
|
10
|
-
wrapRequestBody
|
|
11
|
-
} = require('../core/util')
|
|
12
|
-
|
|
13
|
-
function calculateRetryAfterHeader (retryAfter) {
|
|
14
|
-
const retryTime = new Date(retryAfter).getTime()
|
|
15
|
-
return isNaN(retryTime) ? 0 : retryTime - Date.now()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
class RetryHandler {
|
|
19
|
-
constructor (opts, { dispatch, handler }) {
|
|
20
|
-
const { retryOptions, ...dispatchOpts } = opts
|
|
21
|
-
const {
|
|
22
|
-
// Retry scoped
|
|
23
|
-
retry: retryFn,
|
|
24
|
-
maxRetries,
|
|
25
|
-
maxTimeout,
|
|
26
|
-
minTimeout,
|
|
27
|
-
timeoutFactor,
|
|
28
|
-
// Response scoped
|
|
29
|
-
methods,
|
|
30
|
-
errorCodes,
|
|
31
|
-
retryAfter,
|
|
32
|
-
statusCodes
|
|
33
|
-
} = retryOptions ?? {}
|
|
34
|
-
|
|
35
|
-
this.dispatch = dispatch
|
|
36
|
-
this.handler = WrapHandler.wrap(handler)
|
|
37
|
-
this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) }
|
|
38
|
-
this.retryOpts = {
|
|
39
|
-
retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry],
|
|
40
|
-
retryAfter: retryAfter ?? true,
|
|
41
|
-
maxTimeout: maxTimeout ?? 30 * 1000, // 30s,
|
|
42
|
-
minTimeout: minTimeout ?? 500, // .5s
|
|
43
|
-
timeoutFactor: timeoutFactor ?? 2,
|
|
44
|
-
maxRetries: maxRetries ?? 5,
|
|
45
|
-
// What errors we should retry
|
|
46
|
-
methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'],
|
|
47
|
-
// Indicates which errors to retry
|
|
48
|
-
statusCodes: statusCodes ?? [500, 502, 503, 504, 429],
|
|
49
|
-
// List of errors to retry
|
|
50
|
-
errorCodes: errorCodes ?? [
|
|
51
|
-
'ECONNRESET',
|
|
52
|
-
'ECONNREFUSED',
|
|
53
|
-
'ENOTFOUND',
|
|
54
|
-
'ENETDOWN',
|
|
55
|
-
'ENETUNREACH',
|
|
56
|
-
'EHOSTDOWN',
|
|
57
|
-
'EHOSTUNREACH',
|
|
58
|
-
'EPIPE',
|
|
59
|
-
'UND_ERR_SOCKET'
|
|
60
|
-
]
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.retryCount = 0
|
|
64
|
-
this.retryCountCheckpoint = 0
|
|
65
|
-
this.headersSent = false
|
|
66
|
-
this.start = 0
|
|
67
|
-
this.end = null
|
|
68
|
-
this.etag = null
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
onRequestStart (controller, context) {
|
|
72
|
-
if (!this.headersSent) {
|
|
73
|
-
this.handler.onRequestStart?.(controller, context)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
onRequestUpgrade (controller, statusCode, headers, socket) {
|
|
78
|
-
this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) {
|
|
82
|
-
const { statusCode, code, headers } = err
|
|
83
|
-
const { method, retryOptions } = opts
|
|
84
|
-
const {
|
|
85
|
-
maxRetries,
|
|
86
|
-
minTimeout,
|
|
87
|
-
maxTimeout,
|
|
88
|
-
timeoutFactor,
|
|
89
|
-
statusCodes,
|
|
90
|
-
errorCodes,
|
|
91
|
-
methods
|
|
92
|
-
} = retryOptions
|
|
93
|
-
const { counter } = state
|
|
94
|
-
|
|
95
|
-
// Any code that is not a Undici's originated and allowed to retry
|
|
96
|
-
if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) {
|
|
97
|
-
cb(err)
|
|
98
|
-
return
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// If a set of method are provided and the current method is not in the list
|
|
102
|
-
if (Array.isArray(methods) && !methods.includes(method)) {
|
|
103
|
-
cb(err)
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// If a set of status code are provided and the current status code is not in the list
|
|
108
|
-
if (
|
|
109
|
-
statusCode != null &&
|
|
110
|
-
Array.isArray(statusCodes) &&
|
|
111
|
-
!statusCodes.includes(statusCode)
|
|
112
|
-
) {
|
|
113
|
-
cb(err)
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// If we reached the max number of retries
|
|
118
|
-
if (counter > maxRetries) {
|
|
119
|
-
cb(err)
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let retryAfterHeader = headers?.['retry-after']
|
|
124
|
-
if (retryAfterHeader) {
|
|
125
|
-
retryAfterHeader = Number(retryAfterHeader)
|
|
126
|
-
retryAfterHeader = Number.isNaN(retryAfterHeader)
|
|
127
|
-
? calculateRetryAfterHeader(headers['retry-after'])
|
|
128
|
-
: retryAfterHeader * 1e3 // Retry-After is in seconds
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const retryTimeout =
|
|
132
|
-
retryAfterHeader > 0
|
|
133
|
-
? Math.min(retryAfterHeader, maxTimeout)
|
|
134
|
-
: Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout)
|
|
135
|
-
|
|
136
|
-
setTimeout(() => cb(null), retryTimeout)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
140
|
-
this.retryCount += 1
|
|
141
|
-
|
|
142
|
-
if (statusCode >= 300) {
|
|
143
|
-
if (this.retryOpts.statusCodes.includes(statusCode) === false) {
|
|
144
|
-
this.headersSent = true
|
|
145
|
-
this.handler.onResponseStart?.(
|
|
146
|
-
controller,
|
|
147
|
-
statusCode,
|
|
148
|
-
headers,
|
|
149
|
-
statusMessage
|
|
150
|
-
)
|
|
151
|
-
return
|
|
152
|
-
} else {
|
|
153
|
-
throw new RequestRetryError('Request failed', statusCode, {
|
|
154
|
-
headers,
|
|
155
|
-
data: {
|
|
156
|
-
count: this.retryCount
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Checkpoint for resume from where we left it
|
|
163
|
-
if (this.headersSent) {
|
|
164
|
-
// Only Partial Content 206 supposed to provide Content-Range,
|
|
165
|
-
// any other status code that partially consumed the payload
|
|
166
|
-
// should not be retried because it would result in downstream
|
|
167
|
-
// wrongly concatenate multiple responses.
|
|
168
|
-
if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) {
|
|
169
|
-
throw new RequestRetryError('server does not support the range header and the payload was partially consumed', statusCode, {
|
|
170
|
-
headers,
|
|
171
|
-
data: { count: this.retryCount }
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const contentRange = parseRangeHeader(headers['content-range'])
|
|
176
|
-
// If no content range
|
|
177
|
-
if (!contentRange) {
|
|
178
|
-
throw new RequestRetryError('Content-Range mismatch', statusCode, {
|
|
179
|
-
headers,
|
|
180
|
-
data: { count: this.retryCount }
|
|
181
|
-
})
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Let's start with a weak etag check
|
|
185
|
-
if (this.etag != null && this.etag !== headers.etag) {
|
|
186
|
-
throw new RequestRetryError('ETag mismatch', statusCode, {
|
|
187
|
-
headers,
|
|
188
|
-
data: { count: this.retryCount }
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const { start, size, end = size ? size - 1 : null } = contentRange
|
|
193
|
-
|
|
194
|
-
assert(this.start === start, 'content-range mismatch')
|
|
195
|
-
assert(this.end == null || this.end === end, 'content-range mismatch')
|
|
196
|
-
|
|
197
|
-
return
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (this.end == null) {
|
|
201
|
-
if (statusCode === 206) {
|
|
202
|
-
// First time we receive 206
|
|
203
|
-
const range = parseRangeHeader(headers['content-range'])
|
|
204
|
-
|
|
205
|
-
if (range == null) {
|
|
206
|
-
this.headersSent = true
|
|
207
|
-
this.handler.onResponseStart?.(
|
|
208
|
-
controller,
|
|
209
|
-
statusCode,
|
|
210
|
-
headers,
|
|
211
|
-
statusMessage
|
|
212
|
-
)
|
|
213
|
-
return
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const { start, size, end = size ? size - 1 : null } = range
|
|
217
|
-
assert(
|
|
218
|
-
start != null && Number.isFinite(start),
|
|
219
|
-
'content-range mismatch'
|
|
220
|
-
)
|
|
221
|
-
assert(end != null && Number.isFinite(end), 'invalid content-length')
|
|
222
|
-
|
|
223
|
-
this.start = start
|
|
224
|
-
this.end = end
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// We make our best to checkpoint the body for further range headers
|
|
228
|
-
if (this.end == null) {
|
|
229
|
-
const contentLength = headers['content-length']
|
|
230
|
-
this.end = contentLength != null ? Number(contentLength) - 1 : null
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
assert(Number.isFinite(this.start))
|
|
234
|
-
assert(
|
|
235
|
-
this.end == null || Number.isFinite(this.end),
|
|
236
|
-
'invalid content-length'
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
this.resume = true
|
|
240
|
-
this.etag = headers.etag != null ? headers.etag : null
|
|
241
|
-
|
|
242
|
-
// Weak etags are not useful for comparison nor cache
|
|
243
|
-
// for instance not safe to assume if the response is byte-per-byte
|
|
244
|
-
// equal
|
|
245
|
-
if (
|
|
246
|
-
this.etag != null &&
|
|
247
|
-
this.etag[0] === 'W' &&
|
|
248
|
-
this.etag[1] === '/'
|
|
249
|
-
) {
|
|
250
|
-
this.etag = null
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
this.headersSent = true
|
|
254
|
-
this.handler.onResponseStart?.(
|
|
255
|
-
controller,
|
|
256
|
-
statusCode,
|
|
257
|
-
headers,
|
|
258
|
-
statusMessage
|
|
259
|
-
)
|
|
260
|
-
} else {
|
|
261
|
-
throw new RequestRetryError('Request failed', statusCode, {
|
|
262
|
-
headers,
|
|
263
|
-
data: { count: this.retryCount }
|
|
264
|
-
})
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
onResponseData (controller, chunk) {
|
|
269
|
-
this.start += chunk.length
|
|
270
|
-
|
|
271
|
-
this.handler.onResponseData?.(controller, chunk)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
onResponseEnd (controller, trailers) {
|
|
275
|
-
this.retryCount = 0
|
|
276
|
-
return this.handler.onResponseEnd?.(controller, trailers)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
onResponseError (controller, err) {
|
|
280
|
-
if (controller?.aborted || isDisturbed(this.opts.body)) {
|
|
281
|
-
this.handler.onResponseError?.(controller, err)
|
|
282
|
-
return
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// We reconcile in case of a mix between network errors
|
|
286
|
-
// and server error response
|
|
287
|
-
if (this.retryCount - this.retryCountCheckpoint > 0) {
|
|
288
|
-
// We count the difference between the last checkpoint and the current retry count
|
|
289
|
-
this.retryCount =
|
|
290
|
-
this.retryCountCheckpoint +
|
|
291
|
-
(this.retryCount - this.retryCountCheckpoint)
|
|
292
|
-
} else {
|
|
293
|
-
this.retryCount += 1
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
this.retryOpts.retry(
|
|
297
|
-
err,
|
|
298
|
-
{
|
|
299
|
-
state: { counter: this.retryCount },
|
|
300
|
-
opts: { retryOptions: this.retryOpts, ...this.opts }
|
|
301
|
-
},
|
|
302
|
-
onRetry.bind(this)
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* @this {RetryHandler}
|
|
307
|
-
* @param {Error} [err]
|
|
308
|
-
* @returns
|
|
309
|
-
*/
|
|
310
|
-
function onRetry (err) {
|
|
311
|
-
if (err != null || controller?.aborted || isDisturbed(this.opts.body)) {
|
|
312
|
-
return this.handler.onResponseError?.(controller, err)
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (this.start !== 0) {
|
|
316
|
-
const headers = { range: `bytes=${this.start}-${this.end ?? ''}` }
|
|
317
|
-
|
|
318
|
-
// Weak etag check - weak etags will make comparison algorithms never match
|
|
319
|
-
if (this.etag != null) {
|
|
320
|
-
headers['if-match'] = this.etag
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
this.opts = {
|
|
324
|
-
...this.opts,
|
|
325
|
-
headers: {
|
|
326
|
-
...this.opts.headers,
|
|
327
|
-
...headers
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
try {
|
|
333
|
-
this.retryCountCheckpoint = this.retryCount
|
|
334
|
-
this.dispatch(this.opts, this)
|
|
335
|
-
} catch (err) {
|
|
336
|
-
this.handler.onResponseError?.(controller, err)
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
module.exports = RetryHandler
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { parseHeaders } = require('../core/util')
|
|
4
|
-
const { InvalidArgumentError } = require('../core/errors')
|
|
5
|
-
|
|
6
|
-
const kResume = Symbol('resume')
|
|
7
|
-
|
|
8
|
-
class UnwrapController {
|
|
9
|
-
#paused = false
|
|
10
|
-
#reason = null
|
|
11
|
-
#aborted = false
|
|
12
|
-
#abort
|
|
13
|
-
|
|
14
|
-
[kResume] = null
|
|
15
|
-
|
|
16
|
-
constructor (abort) {
|
|
17
|
-
this.#abort = abort
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
pause () {
|
|
21
|
-
this.#paused = true
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
resume () {
|
|
25
|
-
if (this.#paused) {
|
|
26
|
-
this.#paused = false
|
|
27
|
-
this[kResume]?.()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
abort (reason) {
|
|
32
|
-
if (!this.#aborted) {
|
|
33
|
-
this.#aborted = true
|
|
34
|
-
this.#reason = reason
|
|
35
|
-
this.#abort(reason)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get aborted () {
|
|
40
|
-
return this.#aborted
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
get reason () {
|
|
44
|
-
return this.#reason
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
get paused () {
|
|
48
|
-
return this.#paused
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
module.exports = class UnwrapHandler {
|
|
53
|
-
#handler
|
|
54
|
-
#controller
|
|
55
|
-
|
|
56
|
-
constructor (handler) {
|
|
57
|
-
this.#handler = handler
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
static unwrap (handler) {
|
|
61
|
-
// TODO (fix): More checks...
|
|
62
|
-
return !handler.onRequestStart ? handler : new UnwrapHandler(handler)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
onConnect (abort, context) {
|
|
66
|
-
this.#controller = new UnwrapController(abort)
|
|
67
|
-
this.#handler.onRequestStart?.(this.#controller, context)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
onUpgrade (statusCode, rawHeaders, socket) {
|
|
71
|
-
this.#handler.onRequestUpgrade?.(this.#controller, statusCode, parseHeaders(rawHeaders), socket)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
onHeaders (statusCode, rawHeaders, resume, statusMessage) {
|
|
75
|
-
this.#controller[kResume] = resume
|
|
76
|
-
this.#handler.onResponseStart?.(this.#controller, statusCode, parseHeaders(rawHeaders), statusMessage)
|
|
77
|
-
return !this.#controller.paused
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
onData (data) {
|
|
81
|
-
this.#handler.onResponseData?.(this.#controller, data)
|
|
82
|
-
return !this.#controller.paused
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
onComplete (rawTrailers) {
|
|
86
|
-
this.#handler.onResponseEnd?.(this.#controller, parseHeaders(rawTrailers))
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
onError (err) {
|
|
90
|
-
if (!this.#handler.onResponseError) {
|
|
91
|
-
throw new InvalidArgumentError('invalid onError method')
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
this.#handler.onResponseError?.(this.#controller, err)
|
|
95
|
-
}
|
|
96
|
-
}
|