@zimic/interceptor 1.2.3 → 1.2.4-canary.1

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.
Files changed (34) hide show
  1. package/dist/{chunk-XCYZ5L2M.mjs → chunk-EIYQEPK2.mjs} +111 -85
  2. package/dist/chunk-EIYQEPK2.mjs.map +1 -0
  3. package/dist/{chunk-ZU6IGW27.js → chunk-OKZEX5DQ.js} +111 -85
  4. package/dist/chunk-OKZEX5DQ.js.map +1 -0
  5. package/dist/cli.js +18 -18
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cli.mjs +2 -2
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/http.js +112 -110
  10. package/dist/http.js.map +1 -1
  11. package/dist/http.mjs +112 -110
  12. package/dist/http.mjs.map +1 -1
  13. package/dist/server.js +6 -6
  14. package/dist/server.mjs +1 -1
  15. package/package.json +1 -1
  16. package/src/http/interceptor/HttpInterceptorClient.ts +1 -1
  17. package/src/http/interceptor/HttpInterceptorStore.ts +6 -3
  18. package/src/http/interceptor/RemoteHttpInterceptor.ts +1 -1
  19. package/src/http/interceptor/errors/UnknownHttpInterceptorPlatformError.ts +1 -1
  20. package/src/http/interceptorWorker/HttpInterceptorWorker.ts +3 -5
  21. package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +16 -12
  22. package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +20 -43
  23. package/src/server/InterceptorServer.ts +39 -21
  24. package/src/server/types/schema.ts +1 -1
  25. package/src/utils/http.ts +2 -2
  26. package/src/utils/webSocket.ts +3 -3
  27. package/src/webSocket/WebSocketClient.ts +4 -4
  28. package/src/webSocket/WebSocketHandler.ts +119 -69
  29. package/src/webSocket/WebSocketServer.ts +2 -3
  30. package/src/webSocket/errors/InvalidWebSocketMessageError.ts +8 -0
  31. package/src/webSocket/types.ts +9 -14
  32. package/dist/chunk-XCYZ5L2M.mjs.map +0 -1
  33. package/dist/chunk-ZU6IGW27.js.map +0 -1
  34. package/src/webSocket/errors/InvalidWebSocketMessage.ts +0 -8
package/dist/http.js CHANGED
@@ -58,7 +58,7 @@ var UnknownHttpInterceptorPlatformError = class extends Error {
58
58
  * Ignoring because checking unknown platforms is currently not possible in our Vitest setup. */
59
59
  constructor() {
60
60
  super("Unknown interceptor platform.");
61
- this.name = "UnknownHttpInterceptorPlatform";
61
+ this.name = "UnknownHttpInterceptorPlatformError";
62
62
  }
63
63
  };
64
64
  var UnknownHttpInterceptorPlatformError_default = UnknownHttpInterceptorPlatformError;
@@ -1664,7 +1664,7 @@ var HttpInterceptorClient = class {
1664
1664
  }
1665
1665
  clear() {
1666
1666
  const clearPromises = [
1667
- Promise.resolve(this.workerOrThrow.clearInterceptorHandlers(this))
1667
+ Promise.resolve(this.workerOrThrow.clearHandlers({ interceptor: this }))
1668
1668
  ];
1669
1669
  for (const method of http.HTTP_METHODS) {
1670
1670
  for (const result of this.clearMethodHandlers(method)) {
@@ -1878,19 +1878,19 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1878
1878
  return msw.passthrough();
1879
1879
  }
1880
1880
  }
1881
- clearHandlers() {
1882
- this.internalWorkerOrThrow.resetHandlers();
1883
- for (const handlers of Object.values(this.httpHandlersByMethod)) {
1884
- handlers.length = 0;
1885
- }
1886
- }
1887
- clearInterceptorHandlers(interceptor) {
1881
+ clearHandlers(options = {}) {
1888
1882
  if (!this.isRunning) {
1889
1883
  throw new NotRunningHttpInterceptorError_default();
1890
1884
  }
1891
- for (const methodHandlers of Object.values(this.httpHandlersByMethod)) {
1892
- const groupToRemoveIndex = methodHandlers.findIndex((group) => group.interceptor === interceptor);
1893
- removeArrayIndex(methodHandlers, groupToRemoveIndex);
1885
+ if (options.interceptor === void 0) {
1886
+ for (const handlers of Object.values(this.httpHandlersByMethod)) {
1887
+ handlers.length = 0;
1888
+ }
1889
+ } else {
1890
+ for (const methodHandlers of Object.values(this.httpHandlersByMethod)) {
1891
+ const groupToRemoveIndex = methodHandlers.findIndex((group) => group.interceptor === options.interceptor);
1892
+ removeArrayIndex(methodHandlers, groupToRemoveIndex);
1893
+ }
1894
1894
  }
1895
1895
  }
1896
1896
  get interceptorsWithHandlers() {
@@ -1955,13 +1955,13 @@ var WebSocketTimeoutError = class extends Error {
1955
1955
  var WebSocketOpenTimeoutError = class extends WebSocketTimeoutError {
1956
1956
  constructor(reachedTimeout) {
1957
1957
  super(`Web socket open timed out after ${reachedTimeout}ms.`);
1958
- this.name = "WebSocketOpenTimeout";
1958
+ this.name = "WebSocketOpenTimeoutError";
1959
1959
  }
1960
1960
  };
1961
1961
  var WebSocketMessageTimeoutError = class extends WebSocketTimeoutError {
1962
1962
  constructor(reachedTimeout) {
1963
1963
  super(`Web socket message timed out after ${reachedTimeout}ms.`);
1964
- this.name = "WebSocketMessageTimeout";
1964
+ this.name = "WebSocketMessageTimeoutError";
1965
1965
  }
1966
1966
  };
1967
1967
  var WebSocketMessageAbortError = class extends WebSocketTimeoutError {
@@ -1973,7 +1973,7 @@ var WebSocketMessageAbortError = class extends WebSocketTimeoutError {
1973
1973
  var WebSocketCloseTimeoutError = class extends WebSocketTimeoutError {
1974
1974
  constructor(reachedTimeout) {
1975
1975
  super(`Web socket close timed out after ${reachedTimeout}ms.`);
1976
- this.name = "WebSocketCloseTimeout";
1976
+ this.name = "WebSocketCloseTimeoutError";
1977
1977
  }
1978
1978
  };
1979
1979
  var DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT = 60 * 1e3;
@@ -2061,14 +2061,14 @@ async function closeClientSocket(socket, options = {}) {
2061
2061
  // src/webSocket/constants.ts
2062
2062
  var WEB_SOCKET_CONTROL_MESSAGES = Object.freeze(["socket:auth:valid"]);
2063
2063
 
2064
- // src/webSocket/errors/InvalidWebSocketMessage.ts
2065
- var InvalidWebSocketMessage = class extends Error {
2064
+ // src/webSocket/errors/InvalidWebSocketMessageError.ts
2065
+ var InvalidWebSocketMessageError = class extends Error {
2066
2066
  constructor(message) {
2067
2067
  super(`Web socket message is invalid and could not be parsed: ${message}`);
2068
- this.name = "InvalidWebSocketMessage";
2068
+ this.name = "InvalidWebSocketMessageError";
2069
2069
  }
2070
2070
  };
2071
- var InvalidWebSocketMessage_default = InvalidWebSocketMessage;
2071
+ var InvalidWebSocketMessageError_default = InvalidWebSocketMessageError;
2072
2072
 
2073
2073
  // src/webSocket/errors/NotRunningWebSocketHandlerError.ts
2074
2074
  var NotRunningWebSocketHandlerError = class extends Error {
@@ -2086,7 +2086,7 @@ var WebSocketHandler = class {
2086
2086
  messageTimeout;
2087
2087
  channelListeners = {};
2088
2088
  socketListeners = {
2089
- messageAbort: /* @__PURE__ */ new Map()
2089
+ abortRequests: /* @__PURE__ */ new Map()
2090
2090
  };
2091
2091
  constructor(options) {
2092
2092
  this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
@@ -2107,10 +2107,12 @@ var WebSocketHandler = class {
2107
2107
  }
2108
2108
  socket.addEventListener("error", handleSocketError);
2109
2109
  const handleSocketClose = () => {
2110
+ this.sockets.delete(socket);
2111
+ this.emitSocket("abortRequests", socket);
2112
+ this.socketListeners.abortRequests.delete(socket);
2110
2113
  socket.removeEventListener("message", handleSocketMessage);
2111
2114
  socket.removeEventListener("close", handleSocketClose);
2112
2115
  socket.removeEventListener("error", handleSocketError);
2113
- this.removeSocket(socket);
2114
2116
  };
2115
2117
  socket.addEventListener("close", handleSocketClose);
2116
2118
  this.sockets.add(socket);
@@ -2134,7 +2136,7 @@ var WebSocketHandler = class {
2134
2136
  if (typeof data === "string") {
2135
2137
  return data;
2136
2138
  } else {
2137
- throw new InvalidWebSocketMessage_default(data);
2139
+ throw new InvalidWebSocketMessageError_default(data);
2138
2140
  }
2139
2141
  }
2140
2142
  parseMessage(stringifiedMessage) {
@@ -2142,10 +2144,10 @@ var WebSocketHandler = class {
2142
2144
  try {
2143
2145
  parsedMessage = JSON.parse(stringifiedMessage);
2144
2146
  } catch {
2145
- throw new InvalidWebSocketMessage_default(stringifiedMessage);
2147
+ throw new InvalidWebSocketMessageError_default(stringifiedMessage);
2146
2148
  }
2147
2149
  if (!this.isMessage(parsedMessage)) {
2148
- throw new InvalidWebSocketMessage_default(stringifiedMessage);
2150
+ throw new InvalidWebSocketMessageError_default(stringifiedMessage);
2149
2151
  }
2150
2152
  if (this.isReplyMessage(parsedMessage)) {
2151
2153
  return {
@@ -2164,6 +2166,9 @@ var WebSocketHandler = class {
2164
2166
  isMessage(message) {
2165
2167
  return typeof message === "object" && message !== null && "id" in message && typeof message.id === "string" && "channel" in message && typeof message.channel === "string" && (!("requestId" in message) || typeof message.requestId === "string");
2166
2168
  }
2169
+ isChannelEvent(event, channel) {
2170
+ return event.channel === channel;
2171
+ }
2167
2172
  async notifyListeners(message, socket) {
2168
2173
  if (this.isReplyMessage(message)) {
2169
2174
  await this.notifyReplyListeners(message, socket);
@@ -2192,10 +2197,6 @@ var WebSocketHandler = class {
2192
2197
  });
2193
2198
  await Promise.all(closingPromises);
2194
2199
  }
2195
- removeSocket(socket) {
2196
- this.abortSocketMessages([socket]);
2197
- this.sockets.delete(socket);
2198
- }
2199
2200
  async createEventMessage(channel, eventData) {
2200
2201
  const crypto = await importCrypto();
2201
2202
  const eventMessage = {
@@ -2212,31 +2213,46 @@ var WebSocketHandler = class {
2212
2213
  async request(channel, requestData, options = {}) {
2213
2214
  const request = await this.createEventMessage(channel, requestData);
2214
2215
  this.sendMessage(request, options.sockets);
2215
- const response = await this.waitForReply(channel, request.id, options.sockets);
2216
+ const response = await this.waitForReply(channel, request, options.sockets);
2216
2217
  return response.data;
2217
2218
  }
2218
- async waitForReply(channel, requestId, sockets = this.sockets) {
2219
+ async waitForReply(channel, request, sockets = this.sockets) {
2219
2220
  return new Promise((resolve, reject) => {
2220
2221
  const replyTimeout = setTimeout(() => {
2221
- this.offReply(channel, replyListener);
2222
- this.offAbortSocketMessages(sockets, abortListener);
2222
+ this.offChannel("reply", channel, replyListener);
2223
+ for (const socket of sockets) {
2224
+ this.offSocket("abortRequests", socket, abortRequestsHandler);
2225
+ }
2223
2226
  const timeoutError = new WebSocketMessageTimeoutError(this.messageTimeout);
2224
2227
  reject(timeoutError);
2225
2228
  }, this.messageTimeout);
2226
- const abortListener = this.onAbortSocketMessages(sockets, (error) => {
2229
+ const replyListener = this.onChannel("reply", channel, (message) => {
2230
+ if (message.requestId !== request.id) {
2231
+ return;
2232
+ }
2227
2233
  clearTimeout(replyTimeout);
2228
- this.offReply(channel, replyListener);
2229
- this.offAbortSocketMessages(sockets, abortListener);
2230
- reject(error);
2231
- });
2232
- const replyListener = this.onReply(channel, (message) => {
2233
- if (message.requestId === requestId) {
2234
- clearTimeout(replyTimeout);
2235
- this.offReply(channel, replyListener);
2236
- this.offAbortSocketMessages(sockets, abortListener);
2237
- resolve(message);
2234
+ this.offChannel("reply", channel, replyListener);
2235
+ for (const socket of sockets) {
2236
+ this.offSocket("abortRequests", socket, abortRequestsHandler);
2238
2237
  }
2238
+ resolve(message);
2239
2239
  });
2240
+ const abortRequestsHandler = (options) => {
2241
+ const shouldAbortRequest = options.shouldAbortRequest === void 0 || options.shouldAbortRequest(request);
2242
+ if (!shouldAbortRequest) {
2243
+ return;
2244
+ }
2245
+ clearTimeout(replyTimeout);
2246
+ this.offChannel("reply", channel, replyListener);
2247
+ for (const socket of sockets) {
2248
+ this.offSocket("abortRequests", socket, abortRequestsHandler);
2249
+ }
2250
+ const abortError = new WebSocketMessageAbortError();
2251
+ reject(abortError);
2252
+ };
2253
+ for (const socket of sockets) {
2254
+ this.onSocket("abortRequests", socket, abortRequestsHandler);
2255
+ }
2240
2256
  });
2241
2257
  }
2242
2258
  isReplyMessage(message) {
@@ -2267,9 +2283,9 @@ var WebSocketHandler = class {
2267
2283
  socket.send(stringifiedMessage);
2268
2284
  }
2269
2285
  }
2270
- onEvent(channel, listener) {
2286
+ onChannel(type, channel, listener) {
2271
2287
  const listeners = this.getOrCreateChannelListeners(channel);
2272
- listeners.event.add(listener);
2288
+ listeners[type].add(listener);
2273
2289
  return listener;
2274
2290
  }
2275
2291
  getOrCreateChannelListeners(channel) {
@@ -2282,42 +2298,36 @@ var WebSocketHandler = class {
2282
2298
  }
2283
2299
  return listeners;
2284
2300
  }
2285
- onReply(channel, listener) {
2286
- const listeners = this.getOrCreateChannelListeners(channel);
2287
- listeners.reply.add(listener);
2288
- return listener;
2289
- }
2290
- offEvent(channel, listener) {
2291
- this.channelListeners[channel]?.event.delete(listener);
2292
- }
2293
- offReply(channel, listener) {
2294
- this.channelListeners[channel]?.reply.delete(listener);
2301
+ offChannel(type, channel, listener) {
2302
+ const listeners = this.channelListeners[channel];
2303
+ listeners?.[type].delete(listener);
2295
2304
  }
2296
- removeAllChannelListeners() {
2297
- this.channelListeners = {};
2305
+ onSocket(type, socket, listener) {
2306
+ const listeners = this.getOrCreateSocketListeners(type, socket);
2307
+ listeners.add(listener);
2308
+ return listener;
2298
2309
  }
2299
- onAbortSocketMessages(sockets, listener) {
2300
- for (const socket of sockets) {
2301
- let listeners = this.socketListeners.messageAbort.get(socket);
2302
- if (!listeners) {
2303
- listeners = /* @__PURE__ */ new Set();
2304
- this.socketListeners.messageAbort.set(socket, listeners);
2305
- }
2306
- listeners.add(listener);
2310
+ getOrCreateSocketListeners(type, socket) {
2311
+ const listeners = this.socketListeners[type].get(socket) ?? /* @__PURE__ */ new Set();
2312
+ if (!this.socketListeners[type].has(socket)) {
2313
+ this.socketListeners[type].set(socket, listeners);
2307
2314
  }
2308
- return listener;
2315
+ return listeners;
2309
2316
  }
2310
- offAbortSocketMessages(sockets, listener) {
2311
- for (const socket of sockets) {
2312
- this.socketListeners.messageAbort.get(socket)?.delete(listener);
2317
+ offSocket(type, socket, listener) {
2318
+ const listeners = this.socketListeners[type].get(socket);
2319
+ listeners?.delete(listener);
2320
+ }
2321
+ emitSocket(type, socket, options = {}) {
2322
+ for (const listener of this.socketListeners[type].get(socket) ?? []) {
2323
+ listener(options);
2313
2324
  }
2314
2325
  }
2315
- abortSocketMessages(sockets = this.sockets) {
2316
- const abortError = new WebSocketMessageAbortError();
2317
- for (const socket of sockets) {
2318
- const listeners = this.socketListeners.messageAbort.get(socket) ?? [];
2319
- for (const listener of listeners) {
2320
- listener(abortError);
2326
+ offAny() {
2327
+ this.channelListeners = {};
2328
+ for (const listenersBySocket of Object.values(this.socketListeners)) {
2329
+ for (const listeners of listenersBySocket.values()) {
2330
+ listeners.clear();
2321
2331
  }
2322
2332
  }
2323
2333
  }
@@ -2351,10 +2361,10 @@ var WebSocketClient = class extends WebSocketHandler_default {
2351
2361
  }
2352
2362
  }
2353
2363
  async stop() {
2354
- super.removeAllChannelListeners();
2355
- const sockets = this.socket ? [this.socket] : [];
2356
- super.abortSocketMessages(sockets);
2357
- await super.closeClientSockets(sockets);
2364
+ super.offAny();
2365
+ if (this.socket) {
2366
+ await super.closeClientSockets([this.socket]);
2367
+ }
2358
2368
  this.socket = void 0;
2359
2369
  }
2360
2370
  };
@@ -2382,12 +2392,12 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2382
2392
  }
2383
2393
  async start() {
2384
2394
  await super.sharedStart(async () => {
2395
+ this.webSocketClient.onChannel("event", "interceptors/responses/create", this.createResponse);
2396
+ this.webSocketClient.onChannel("event", "interceptors/responses/unhandled", this.handleUnhandledServerRequest);
2385
2397
  await this.webSocketClient.start({
2386
2398
  parameters: this.auth ? { token: this.auth.token } : void 0,
2387
2399
  waitForAuthentication: true
2388
2400
  });
2389
- this.webSocketClient.onEvent("interceptors/responses/create", this.createResponse);
2390
- this.webSocketClient.onEvent("interceptors/responses/unhandled", this.handleUnhandledServerRequest);
2391
2401
  this.platform = this.readPlatform();
2392
2402
  this.isRunning = true;
2393
2403
  });
@@ -2427,9 +2437,9 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2427
2437
  }
2428
2438
  async stop() {
2429
2439
  await super.sharedStop(async () => {
2440
+ this.webSocketClient.offChannel("event", "interceptors/responses/create", this.createResponse);
2441
+ this.webSocketClient.offChannel("event", "interceptors/responses/unhandled", this.handleUnhandledServerRequest);
2430
2442
  await this.clearHandlers();
2431
- this.webSocketClient.offEvent("interceptors/responses/create", this.createResponse);
2432
- this.webSocketClient.offEvent("interceptors/responses/unhandled", this.handleUnhandledServerRequest);
2433
2443
  await this.webSocketClient.stop();
2434
2444
  this.isRunning = false;
2435
2445
  });
@@ -2459,43 +2469,30 @@ var RemoteHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
2459
2469
  path: handler.path
2460
2470
  });
2461
2471
  }
2462
- async clearHandlers() {
2463
- if (!this.isRunning) {
2464
- throw new NotRunningHttpInterceptorError_default();
2465
- }
2466
- this.httpHandlers.clear();
2467
- if (!this.webSocketClient.isRunning) {
2468
- return;
2469
- }
2470
- try {
2471
- await this.webSocketClient.request("interceptors/workers/reset", void 0);
2472
- } catch (error) {
2473
- const isMessageAbortError = error instanceof WebSocketMessageAbortError;
2474
- if (!isMessageAbortError) {
2475
- throw error;
2476
- }
2477
- }
2478
- }
2479
- async clearInterceptorHandlers(interceptor) {
2472
+ async clearHandlers(options = {}) {
2480
2473
  if (!this.isRunning) {
2481
2474
  throw new NotRunningHttpInterceptorError_default();
2482
2475
  }
2483
- for (const handler of this.httpHandlers.values()) {
2484
- if (handler.interceptor === interceptor) {
2485
- this.httpHandlers.delete(handler.id);
2476
+ if (options.interceptor === void 0) {
2477
+ this.httpHandlers.clear();
2478
+ } else {
2479
+ for (const handler of this.httpHandlers.values()) {
2480
+ if (handler.interceptor === options.interceptor) {
2481
+ this.httpHandlers.delete(handler.id);
2482
+ }
2486
2483
  }
2487
2484
  }
2488
2485
  if (!this.webSocketClient.isRunning) {
2489
2486
  return;
2490
2487
  }
2491
- const groupsToRecommit = Array.from(this.httpHandlers.values(), (handler) => ({
2488
+ const handlersToRecommit = Array.from(this.httpHandlers.values(), (handler) => ({
2492
2489
  id: handler.id,
2493
2490
  baseURL: handler.baseURL,
2494
2491
  method: handler.method,
2495
2492
  path: handler.path
2496
2493
  }));
2497
2494
  try {
2498
- await this.webSocketClient.request("interceptors/workers/reset", groupsToRecommit);
2495
+ await this.webSocketClient.request("interceptors/workers/reset", handlersToRecommit);
2499
2496
  } catch (error) {
2500
2497
  const isMessageAbortError = error instanceof WebSocketMessageAbortError;
2501
2498
  if (!isMessageAbortError) {
@@ -2530,10 +2527,11 @@ var HttpInterceptorStore = class _HttpInterceptorStore {
2530
2527
  return this.class._localWorker;
2531
2528
  }
2532
2529
  getRemoteWorkerKey(baseURL, options) {
2533
- if (!options.auth) {
2534
- return baseURL.origin;
2530
+ const key = [`${baseURL.origin}${baseURL.pathname}`];
2531
+ if (options.auth) {
2532
+ key.push(options.auth.token);
2535
2533
  }
2536
- return `${baseURL.origin}:${options.auth.token}`;
2534
+ return key.join(":");
2537
2535
  }
2538
2536
  remoteWorker(baseURL, options) {
2539
2537
  const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options);
@@ -2698,7 +2696,7 @@ var RemoteHttpInterceptor = class {
2698
2696
  baseURL,
2699
2697
  createWorker: () => {
2700
2698
  return this.store.getOrCreateRemoteWorker({
2701
- serverURL: new URL(baseURL.origin),
2699
+ serverURL: baseURL,
2702
2700
  auth: this._auth
2703
2701
  });
2704
2702
  },
@@ -2832,6 +2830,8 @@ var InvalidJSONError = class extends http.InvalidJSONError {
2832
2830
  };
2833
2831
  /* istanbul ignore next -- @preserve
2834
2832
  * Ignoring because there will always be a handler for the given method and path at this point. */
2833
+ /* istanbul ignore if -- @preserve
2834
+ * Trying to access the internal worker when it does not exist should not happen. */
2835
2835
  /* istanbul ignore else -- @preserve */
2836
2836
  /* istanbul ignore next -- @preserve
2837
2837
  * Ignoring because checking unknown platforms is not configured in our test setup. */
@@ -2848,6 +2848,8 @@ var InvalidJSONError = class extends http.InvalidJSONError {
2848
2848
  /* istanbul ignore next -- @preserve
2849
2849
  * Reply listeners are always present when notified in normal conditions. If they were not present, the request
2850
2850
  * would reach a timeout and not be responded. The empty set serves as a fallback. */
2851
+ /* istanbul ignore if -- @preserve
2852
+ * Aborting requests is highly non-deterministic because it depends on specific timing of socket events. */
2851
2853
  /* istanbul ignore next -- @preserve
2852
2854
  *
2853
2855
  * If the socket is closed before receiving a response, the message is aborted with an error. This can happen if