Skip to content

Commit f670f2a

Browse files
authored
feat: make UndiciErrors reliable to instanceof (#4472) (#4480)
* feat: make UndiciErrors reliable to instanceof * also take MockNotMatchedError into account (cherry picked from commit 5f256af)
1 parent 422e397 commit f670f2a

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

lib/core/errors.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,85 @@
11
'use strict'
22

3+
const kUndiciError = Symbol.for('undici.error.UND_ERR')
34
class UndiciError extends Error {
45
constructor (message) {
56
super(message)
67
this.name = 'UndiciError'
78
this.code = 'UND_ERR'
89
}
10+
11+
static [Symbol.hasInstance] (instance) {
12+
return instance && instance[kUndiciError] === true
13+
}
14+
15+
[kUndiciError] = true
916
}
1017

18+
const kConnectTimeoutError = Symbol.for('undici.error.UND_ERR_CONNECT_TIMEOUT')
1119
class ConnectTimeoutError extends UndiciError {
1220
constructor (message) {
1321
super(message)
1422
this.name = 'ConnectTimeoutError'
1523
this.message = message || 'Connect Timeout Error'
1624
this.code = 'UND_ERR_CONNECT_TIMEOUT'
1725
}
26+
27+
static [Symbol.hasInstance] (instance) {
28+
return instance && instance[kConnectTimeoutError] === true
29+
}
30+
31+
[kConnectTimeoutError] = true
1832
}
1933

34+
const kHeadersTimeoutError = Symbol.for('undici.error.UND_ERR_HEADERS_TIMEOUT')
2035
class HeadersTimeoutError extends UndiciError {
2136
constructor (message) {
2237
super(message)
2338
this.name = 'HeadersTimeoutError'
2439
this.message = message || 'Headers Timeout Error'
2540
this.code = 'UND_ERR_HEADERS_TIMEOUT'
2641
}
42+
43+
static [Symbol.hasInstance] (instance) {
44+
return instance && instance[kHeadersTimeoutError] === true
45+
}
46+
47+
[kHeadersTimeoutError] = true
2748
}
2849

50+
const kHeadersOverflowError = Symbol.for('undici.error.UND_ERR_HEADERS_OVERFLOW')
2951
class HeadersOverflowError extends UndiciError {
3052
constructor (message) {
3153
super(message)
3254
this.name = 'HeadersOverflowError'
3355
this.message = message || 'Headers Overflow Error'
3456
this.code = 'UND_ERR_HEADERS_OVERFLOW'
3557
}
58+
59+
static [Symbol.hasInstance] (instance) {
60+
return instance && instance[kHeadersOverflowError] === true
61+
}
62+
63+
[kHeadersOverflowError] = true
3664
}
3765

66+
const kBodyTimeoutError = Symbol.for('undici.error.UND_ERR_BODY_TIMEOUT')
3867
class BodyTimeoutError extends UndiciError {
3968
constructor (message) {
4069
super(message)
4170
this.name = 'BodyTimeoutError'
4271
this.message = message || 'Body Timeout Error'
4372
this.code = 'UND_ERR_BODY_TIMEOUT'
4473
}
74+
75+
static [Symbol.hasInstance] (instance) {
76+
return instance && instance[kBodyTimeoutError] === true
77+
}
78+
79+
[kBodyTimeoutError] = true
4580
}
4681

82+
const kResponseStatusCodeError = Symbol.for('undici.error.UND_ERR_RESPONSE_STATUS_CODE')
4783
class ResponseStatusCodeError extends UndiciError {
4884
constructor (message, statusCode, headers, body) {
4985
super(message)
@@ -55,88 +91,159 @@ class ResponseStatusCodeError extends UndiciError {
5591
this.statusCode = statusCode
5692
this.headers = headers
5793
}
94+
95+
static [Symbol.hasInstance] (instance) {
96+
return instance && instance[kResponseStatusCodeError] === true
97+
}
98+
99+
[kResponseStatusCodeError] = true
58100
}
59101

102+
const kInvalidArgumentError = Symbol.for('undici.error.UND_ERR_INVALID_ARG')
60103
class InvalidArgumentError extends UndiciError {
61104
constructor (message) {
62105
super(message)
63106
this.name = 'InvalidArgumentError'
64107
this.message = message || 'Invalid Argument Error'
65108
this.code = 'UND_ERR_INVALID_ARG'
66109
}
110+
111+
static [Symbol.hasInstance] (instance) {
112+
return instance && instance[kInvalidArgumentError] === true
113+
}
114+
115+
[kInvalidArgumentError] = true
67116
}
68117

118+
const kInvalidReturnValueError = Symbol.for('undici.error.UND_ERR_INVALID_RETURN_VALUE')
69119
class InvalidReturnValueError extends UndiciError {
70120
constructor (message) {
71121
super(message)
72122
this.name = 'InvalidReturnValueError'
73123
this.message = message || 'Invalid Return Value Error'
74124
this.code = 'UND_ERR_INVALID_RETURN_VALUE'
75125
}
126+
127+
static [Symbol.hasInstance] (instance) {
128+
return instance && instance[kInvalidReturnValueError] === true
129+
}
130+
131+
[kInvalidReturnValueError] = true
76132
}
77133

134+
const kAbortError = Symbol.for('undici.error.UND_ERR_ABORT')
78135
class AbortError extends UndiciError {
79136
constructor (message) {
80137
super(message)
81138
this.name = 'AbortError'
82139
this.message = message || 'The operation was aborted'
140+
this.code = 'UND_ERR_ABORT'
141+
}
142+
143+
static [Symbol.hasInstance] (instance) {
144+
return instance && instance[kAbortError] === true
83145
}
146+
147+
[kAbortError] = true
84148
}
85149

150+
const kRequestAbortedError = Symbol.for('undici.error.UND_ERR_ABORTED')
86151
class RequestAbortedError extends AbortError {
87152
constructor (message) {
88153
super(message)
89154
this.name = 'AbortError'
90155
this.message = message || 'Request aborted'
91156
this.code = 'UND_ERR_ABORTED'
92157
}
158+
159+
static [Symbol.hasInstance] (instance) {
160+
return instance && instance[kRequestAbortedError] === true
161+
}
162+
163+
[kRequestAbortedError] = true
93164
}
94165

166+
const kInformationalError = Symbol.for('undici.error.UND_ERR_INFO')
95167
class InformationalError extends UndiciError {
96168
constructor (message) {
97169
super(message)
98170
this.name = 'InformationalError'
99171
this.message = message || 'Request information'
100172
this.code = 'UND_ERR_INFO'
101173
}
174+
175+
static [Symbol.hasInstance] (instance) {
176+
return instance && instance[kInformationalError] === true
177+
}
178+
179+
[kInformationalError] = true
102180
}
103181

182+
const kRequestContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_REQ_CONTENT_LENGTH_MISMATCH')
104183
class RequestContentLengthMismatchError extends UndiciError {
105184
constructor (message) {
106185
super(message)
107186
this.name = 'RequestContentLengthMismatchError'
108187
this.message = message || 'Request body length does not match content-length header'
109188
this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
110189
}
190+
191+
static [Symbol.hasInstance] (instance) {
192+
return instance && instance[kRequestContentLengthMismatchError] === true
193+
}
194+
195+
[kRequestContentLengthMismatchError] = true
111196
}
112197

198+
const kResponseContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_RES_CONTENT_LENGTH_MISMATCH')
113199
class ResponseContentLengthMismatchError extends UndiciError {
114200
constructor (message) {
115201
super(message)
116202
this.name = 'ResponseContentLengthMismatchError'
117203
this.message = message || 'Response body length does not match content-length header'
118204
this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH'
119205
}
206+
207+
static [Symbol.hasInstance] (instance) {
208+
return instance && instance[kResponseContentLengthMismatchError] === true
209+
}
210+
211+
[kResponseContentLengthMismatchError] = true
120212
}
121213

214+
const kClientDestroyedError = Symbol.for('undici.error.UND_ERR_DESTROYED')
122215
class ClientDestroyedError extends UndiciError {
123216
constructor (message) {
124217
super(message)
125218
this.name = 'ClientDestroyedError'
126219
this.message = message || 'The client is destroyed'
127220
this.code = 'UND_ERR_DESTROYED'
128221
}
222+
223+
static [Symbol.hasInstance] (instance) {
224+
return instance && instance[kClientDestroyedError] === true
225+
}
226+
227+
[kClientDestroyedError] = true
129228
}
130229

230+
const kClientClosedError = Symbol.for('undici.error.UND_ERR_CLOSED')
131231
class ClientClosedError extends UndiciError {
132232
constructor (message) {
133233
super(message)
134234
this.name = 'ClientClosedError'
135235
this.message = message || 'The client is closed'
136236
this.code = 'UND_ERR_CLOSED'
137237
}
238+
239+
static [Symbol.hasInstance] (instance) {
240+
return instance && instance[kClientClosedError] === true
241+
}
242+
243+
[kClientClosedError] = true
138244
}
139245

246+
const kSocketError = Symbol.for('undici.error.UND_ERR_SOCKET')
140247
class SocketError extends UndiciError {
141248
constructor (message, socket) {
142249
super(message)
@@ -145,44 +252,79 @@ class SocketError extends UndiciError {
145252
this.code = 'UND_ERR_SOCKET'
146253
this.socket = socket
147254
}
255+
256+
static [Symbol.hasInstance] (instance) {
257+
return instance && instance[kSocketError] === true
258+
}
259+
260+
[kSocketError] = true
148261
}
149262

263+
const kNotSupportedError = Symbol.for('undici.error.UND_ERR_NOT_SUPPORTED')
150264
class NotSupportedError extends UndiciError {
151265
constructor (message) {
152266
super(message)
153267
this.name = 'NotSupportedError'
154268
this.message = message || 'Not supported error'
155269
this.code = 'UND_ERR_NOT_SUPPORTED'
156270
}
271+
272+
static [Symbol.hasInstance] (instance) {
273+
return instance && instance[kNotSupportedError] === true
274+
}
275+
276+
[kNotSupportedError] = true
157277
}
158278

279+
const kBalancedPoolMissingUpstreamError = Symbol.for('undici.error.UND_ERR_BPL_MISSING_UPSTREAM')
159280
class BalancedPoolMissingUpstreamError extends UndiciError {
160281
constructor (message) {
161282
super(message)
162283
this.name = 'MissingUpstreamError'
163284
this.message = message || 'No upstream has been added to the BalancedPool'
164285
this.code = 'UND_ERR_BPL_MISSING_UPSTREAM'
165286
}
287+
288+
static [Symbol.hasInstance] (instance) {
289+
return instance && instance[kBalancedPoolMissingUpstreamError] === true
290+
}
291+
292+
[kBalancedPoolMissingUpstreamError] = true
166293
}
167294

295+
const kHTTPParserError = Symbol.for('undici.error.UND_ERR_HTTP_PARSER')
168296
class HTTPParserError extends Error {
169297
constructor (message, code, data) {
170298
super(message)
171299
this.name = 'HTTPParserError'
172300
this.code = code ? `HPE_${code}` : undefined
173301
this.data = data ? data.toString() : undefined
174302
}
303+
304+
static [Symbol.hasInstance] (instance) {
305+
return instance && instance[kHTTPParserError] === true
306+
}
307+
308+
[kHTTPParserError] = true
175309
}
176310

311+
const kResponseExceededMaxSizeError = Symbol.for('undici.error.UND_ERR_RES_EXCEEDED_MAX_SIZE')
177312
class ResponseExceededMaxSizeError extends UndiciError {
178313
constructor (message) {
179314
super(message)
180315
this.name = 'ResponseExceededMaxSizeError'
181316
this.message = message || 'Response content exceeded max size'
182317
this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE'
183318
}
319+
320+
static [Symbol.hasInstance] (instance) {
321+
return instance && instance[kResponseExceededMaxSizeError] === true
322+
}
323+
324+
[kResponseExceededMaxSizeError] = true
184325
}
185326

327+
const kRequestRetryError = Symbol.for('undici.error.UND_ERR_REQ_RETRY')
186328
class RequestRetryError extends UndiciError {
187329
constructor (message, code, { headers, data }) {
188330
super(message)
@@ -193,8 +335,15 @@ class RequestRetryError extends UndiciError {
193335
this.data = data
194336
this.headers = headers
195337
}
338+
339+
static [Symbol.hasInstance] (instance) {
340+
return instance && instance[kRequestRetryError] === true
341+
}
342+
343+
[kRequestRetryError] = true
196344
}
197345

346+
const kResponseError = Symbol.for('undici.error.UND_ERR_RESPONSE')
198347
class ResponseError extends UndiciError {
199348
constructor (message, code, { headers, data }) {
200349
super(message)
@@ -205,8 +354,15 @@ class ResponseError extends UndiciError {
205354
this.data = data
206355
this.headers = headers
207356
}
357+
358+
static [Symbol.hasInstance] (instance) {
359+
return instance && instance[kResponseError] === true
360+
}
361+
362+
[kResponseError] = true
208363
}
209364

365+
const kSecureProxyConnectionError = Symbol.for('undici.error.UND_ERR_PRX_TLS')
210366
class SecureProxyConnectionError extends UndiciError {
211367
constructor (cause, message, options) {
212368
super(message, { cause, ...(options ?? {}) })
@@ -215,6 +371,12 @@ class SecureProxyConnectionError extends UndiciError {
215371
this.code = 'UND_ERR_PRX_TLS'
216372
this.cause = cause
217373
}
374+
375+
static [Symbol.hasInstance] (instance) {
376+
return instance && instance[kSecureProxyConnectionError] === true
377+
}
378+
379+
[kSecureProxyConnectionError] = true
218380
}
219381

220382
module.exports = {

lib/mock/mock-errors.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
const { UndiciError } = require('../core/errors')
44

5+
const kMockNotMatchedError = Symbol.for('undici.error.UND_MOCK_ERR_MOCK_NOT_MATCHED')
6+
7+
/**
8+
* The request does not match any registered mock dispatches.
9+
*/
510
class MockNotMatchedError extends UndiciError {
611
constructor (message) {
712
super(message)
@@ -10,6 +15,12 @@ class MockNotMatchedError extends UndiciError {
1015
this.message = message || 'The request does not match any registered mock dispatches'
1116
this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED'
1217
}
18+
19+
static [Symbol.hasInstance] (instance) {
20+
return instance && instance[kMockNotMatchedError] === true
21+
}
22+
23+
[kMockNotMatchedError] = true
1324
}
1425

1526
module.exports = {

0 commit comments

Comments
 (0)