got 9.3.2 → 9.6.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "got",
3
- "version": "9.3.2",
3
+ "version": "9.6.0",
4
4
  "description": "Simplified HTTP requests",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/got",
@@ -34,9 +34,9 @@
34
34
  "electron"
35
35
  ],
36
36
  "dependencies": {
37
- "@sindresorhus/is": "^0.12.0",
38
- "@szmarczak/http-timer": "^1.1.0",
39
- "cacheable-request": "^5.1.0",
37
+ "@sindresorhus/is": "^0.14.0",
38
+ "@szmarczak/http-timer": "^1.1.2",
39
+ "cacheable-request": "^6.0.0",
40
40
  "decompress-response": "^3.3.0",
41
41
  "duplexer3": "^0.1.4",
42
42
  "get-stream": "^4.1.0",
@@ -47,22 +47,22 @@
47
47
  "url-parse-lax": "^3.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "ava": "1.0.0-rc.1",
50
+ "ava": "^1.1.0",
51
51
  "coveralls": "^3.0.0",
52
52
  "delay": "^4.1.0",
53
53
  "form-data": "^2.3.3",
54
54
  "get-port": "^4.0.0",
55
- "np": "^3.0.4",
55
+ "np": "^3.1.0",
56
56
  "nyc": "^13.1.0",
57
57
  "p-event": "^2.1.0",
58
58
  "pem": "^1.13.2",
59
59
  "proxyquire": "^2.0.1",
60
- "sinon": "^7.1.0",
60
+ "sinon": "^7.2.2",
61
61
  "slow-stream": "0.0.4",
62
62
  "tempfile": "^2.0.0",
63
63
  "tempy": "^0.2.1",
64
- "tough-cookie": "^2.4.3",
65
- "xo": "^0.23.0"
64
+ "tough-cookie": "^3.0.0",
65
+ "xo": "^0.24.0"
66
66
  },
67
67
  "ava": {
68
68
  "concurrency": 4
package/readme.md CHANGED
@@ -35,15 +35,16 @@ Got is for Node.js. For browsers, we recommend [Ky](https://github.com/sindresor
35
35
  - [Errors with metadata](#errors)
36
36
  - [JSON mode](#json)
37
37
  - [WHATWG URL support](#url)
38
- - [Hooks](https://github.com/sindresorhus/got#hooks)
38
+ - [Hooks](#hooks)
39
39
  - [Instances with custom defaults](#instances)
40
40
  - [Composable](advanced-creation.md#merging-instances)
41
41
  - [Electron support](#useelectronnet)
42
42
  - [Used by ~2000 packages and ~500K repos](https://github.com/sindresorhus/got/network/dependents)
43
43
  - Actively maintained
44
44
 
45
- [See how Got compares to other HTTP libraries](#comparison)
45
+ [Moving from Request?](migration-guides.md)
46
46
 
47
+ [See how Got compares to other HTTP libraries](#comparison)
47
48
 
48
49
  ## Install
49
50
 
@@ -154,7 +155,7 @@ Returns a `Stream` instead of a `Promise`. This is equivalent to calling `got.st
154
155
 
155
156
  Type: `string` `Buffer` `stream.Readable` [`form-data` instance](https://github.com/form-data/form-data)
156
157
 
157
- *If you provide this option, `got.stream()` will be read-only.*
158
+ **Note:** If you provide this option, `got.stream()` will be read-only.
158
159
 
159
160
  The body that will be sent with a `POST` request.
160
161
 
@@ -166,9 +167,9 @@ The `content-length` header will be automatically set if `body` is a `string` /
166
167
 
167
168
  Type: [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)
168
169
 
169
- Cookie support. You don't have to care about parsing or how to store them. [Example.](#cookies)
170
+ **Note:** If you provide this option, `options.headers.cookie` will be overridden.
170
171
 
171
- **Note:** `options.headers.cookie` will be overridden.
172
+ Cookie support. You don't have to care about parsing or how to store them. [Example.](#cookies)
172
173
 
173
174
  ###### encoding
174
175
 
@@ -182,25 +183,23 @@ Default: `'utf8'`
182
183
  Type: `boolean`<br>
183
184
  Default: `false`
184
185
 
185
- *If you provide this option, `got.stream()` will be read-only.*
186
+ **Note:** If you provide this option, `got.stream()` will be read-only.
187
+ **Note:** `body` must be a plain object. It will be converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
186
188
 
187
189
  If set to `true` and `Content-Type` header is not set, it will be set to `application/x-www-form-urlencoded`.
188
190
 
189
- `body` must be a plain object. It will be converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
190
-
191
191
  ###### json
192
192
 
193
193
  Type: `boolean`<br>
194
194
  Default: `false`
195
195
 
196
- *If you use `got.stream()`, this option will be ignored.*
196
+ **Note:** If you use `got.stream()`, this option will be ignored.
197
+ **Note:** `body` must be a plain object or array and will be stringified.
197
198
 
198
199
  If set to `true` and `Content-Type` header is not set, it will be set to `application/json`.
199
200
 
200
201
  Parse response body with `JSON.parse` and set `accept` header to `application/json`. If used in conjunction with the `form` option, the `body` will the stringified as querystring and the response parsed as JSON.
201
202
 
202
- `body` must be a plain object or array and will be stringified.
203
-
204
203
  ###### query
205
204
 
206
205
  Type: `string` `Object<string, string|number>` [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
@@ -258,8 +257,9 @@ Default:
258
257
  - methods: `GET` `PUT` `HEAD` `DELETE` `OPTIONS` `TRACE`
259
258
  - statusCodes: [`408`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) [`413`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) [`429`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) [`500`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) [`502`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) [`503`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) [`504`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504)
260
259
  - maxRetryAfter: `undefined`
260
+ - errorCodes: `ETIMEDOUT` `ECONNRESET` `EADDRINUSE` `ECONNREFUSED` `EPIPE` `ENOTFOUND` `ENETUNREACH` `EAI_AGAIN`
261
261
 
262
- An object representing `retries`, `methods`, `statusCodes` and `maxRetryAfter` fields for the time until retry, allowed methods, allowed status codes and maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time.
262
+ An object representing `retries`, `methods`, `statusCodes`, `maxRetryAfter` and `errorCodes` fields for the time until retry, allowed methods, allowed status codes, maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time and allowed error codes.
263
263
 
264
264
  If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`.<br>
265
265
  If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request.
@@ -268,12 +268,15 @@ Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.ra
268
268
 
269
269
  The `retries` property can be a `number` or a `function` with `retry` and `error` arguments. The function must return a delay in milliseconds (`0` return value cancels retry).
270
270
 
271
- **Note:** It retries only on the specified methods, status codes, and on these network errors:
271
+ By default, it retries *only* on the specified methods, status codes, and on these network errors:
272
272
  - `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
273
273
  - `ECONNRESET`: Connection was forcibly closed by a peer.
274
274
  - `EADDRINUSE`: Could not bind to any free port.
275
275
  - `ECONNREFUSED`: Connection was refused by the server.
276
276
  - `EPIPE`: The remote side of the stream being written has been closed.
277
+ - `ENOTFOUND`: Couldn't resolve the hostname to an IP address.
278
+ - `ENETUNREACH`: No internet connection.
279
+ - `EAI_AGAIN`: DNS lookup timed out.
277
280
 
278
281
  ###### followRedirect
279
282
 
@@ -348,6 +351,17 @@ Type: `Object<string, Function[]>`
348
351
 
349
352
  Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
350
353
 
354
+ ###### hooks.init
355
+
356
+ Type: `Function[]`<br>
357
+ Default: `[]`
358
+
359
+ Called with plain [request options](#options), right before their normalization. This is especially useful in conjunction with [`got.extend()`](#instances) and [`got.create()`](advanced-creation.md) when the input needs custom handling.
360
+
361
+ See the [Request migration guide](migration-guides.md#breaking-changes) for an example.
362
+
363
+ **Note**: This hook must be synchronous!
364
+
351
365
  ###### hooks.beforeRequest
352
366
 
353
367
  Type: `Function[]`<br>
@@ -357,7 +371,7 @@ Called with [normalized](source/normalize-arguments.js) [request options](#optio
357
371
 
358
372
  See the [AWS section](#aws) for an example.
359
373
 
360
- **Note**: If you modify the `body` you will need to modify the `content-length` header too, because it has already been computed and assigned.
374
+ **Note:** If you modify the `body` you will need to modify the `content-length` header too, because it has already been computed and assigned.
361
375
 
362
376
  ###### hooks.beforeRedirect
363
377
 
@@ -444,10 +458,47 @@ const instance = got.extend({
444
458
  });
445
459
  ```
446
460
 
461
+ ###### hooks.beforeError
462
+
463
+ Type: `Function[]`<br>
464
+ Default: `[]`
465
+
466
+ Called with an `Error` instance. The error is passed to the hook right before it's thrown. This is especially useful when you want to have more detailed errors.
467
+
468
+ **Note**: Errors thrown while normalizing input options are thrown directly and not part of this hook.
469
+
470
+ ```js
471
+ const got = require('got');
472
+
473
+ got('api.github.com/some-endpoint', {
474
+ hooks: {
475
+ onError: [
476
+ error => {
477
+ const {response} = error;
478
+ if (response && response.body) {
479
+ error.name = 'GitHubError';
480
+ error.message = `${response.body.message} (${error.statusCode})`;
481
+ }
482
+
483
+ return error;
484
+ }
485
+ ]
486
+ }
487
+ });
488
+ ```
489
+
447
490
  #### Response
448
491
 
449
492
  The response object will typically be a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage), however, if returned from the cache it will be a [response-like object](https://github.com/lukechilds/responselike) which behaves in the same way.
450
493
 
494
+ ##### request
495
+
496
+ Type: `Object`
497
+
498
+ **Note:** This is not a [http.ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest).
499
+
500
+ - `gotOptions` - The options that were set on this request.
501
+
451
502
  ##### body
452
503
 
453
504
  Type: `string` `Object` *(depending on `options.json`)*
@@ -489,7 +540,7 @@ The object contains the following properties:
489
540
  - `download` - `timings.end - timings.response`
490
541
  - `total` - `timings.end - timings.start` or `timings.error - timings.start`
491
542
 
492
- **Note**: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
543
+ **Note:** The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
493
544
 
494
545
  ##### fromCache
495
546
 
@@ -511,7 +562,7 @@ The number of times the request was retried.
511
562
 
512
563
  #### Streams
513
564
 
514
- **Note**: Progress events, redirect events and request/response events can also be used with promises.
565
+ **Note:** Progress events, redirect events and request/response events can also be used with promises.
515
566
 
516
567
  #### got.stream(url, [options])
517
568
 
@@ -523,7 +574,7 @@ Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream
523
574
 
524
575
  `request` event to get the request object of the request.
525
576
 
526
- **Tip**: You can use `request` event to abort request:
577
+ **Tip:** You can use `request` event to abort request:
527
578
 
528
579
  ```js
529
580
  got.stream('github.com')
@@ -626,7 +677,7 @@ client.get('/demo');
626
677
  })();
627
678
  ```
628
679
 
629
- *Need more control over the behavior of Got? Check out the [`got.create()`](advanced-creation.md).*
680
+ **Tip:** Need more control over the behavior of Got? Check out the [`got.create()`](advanced-creation.md).
630
681
 
631
682
  #### got.mergeOptions(parentOptions, newOptions)
632
683
 
@@ -658,7 +709,7 @@ The default Got options.
658
709
 
659
710
  ## Errors
660
711
 
661
- Each error contains (if available) `body`, `statusCode`, `statusMessage`, `host`, `hostname`, `method`, `path`, `protocol` and `url` properties to make debugging easier.
712
+ Each error contains `host`, `hostname`, `method`, `path`, `protocol`, `url` and `gotOptions` properties to make debugging easier.
662
713
 
663
714
  In Promise mode, the `response` is attached to the error.
664
715
 
@@ -676,15 +727,15 @@ When reading from response stream fails.
676
727
 
677
728
  #### got.ParseError
678
729
 
679
- When `json` option is enabled, server response code is 2xx, and `JSON.parse` fails.
730
+ When `json` option is enabled, server response code is 2xx, and `JSON.parse` fails. Includes `statusCode` and `statusMessage` properties.
680
731
 
681
732
  #### got.HTTPError
682
733
 
683
- When the server response code is not 2xx. Includes `statusCode`, `statusMessage`, and `redirectUrls` properties.
734
+ When the server response code is not 2xx. Includes `body`, `statusCode`, `statusMessage`, and `redirectUrls` properties.
684
735
 
685
736
  #### got.MaxRedirectsError
686
737
 
687
- When the server redirects you more than ten times. Includes a `redirectUrls` property, which is an array of the URLs Got was redirected to before giving up.
738
+ When the server redirects you more than ten times. Includes a `statusCode`, `statusMessage`, and `redirectUrls` property which is an array of the URLs Got was redirected to before giving up.
688
739
 
689
740
  #### got.UnsupportedProtocolError
690
741
 
@@ -696,7 +747,7 @@ When the request is aborted with `.cancel()`.
696
747
 
697
748
  #### got.TimeoutError
698
749
 
699
- When the request is aborted due to a [timeout](#timeout)
750
+ When the request is aborted due to a [timeout](#timeout). Includes an `event` property.
700
751
 
701
752
  ## Aborting the request
702
753
 
@@ -1002,7 +1053,7 @@ const custom = got.extend({
1002
1053
  })();
1003
1054
  ```
1004
1055
 
1005
- *Need to merge some instances into a single one? Check out [`got.mergeInstances()`](advanced-creation.md#merging-instances).*
1056
+ **Tip:** Need to merge some instances into a single one? Check out [`got.mergeInstances()`](advanced-creation.md#merging-instances).
1006
1057
 
1007
1058
  ### Experimental HTTP2 support
1008
1059
 
@@ -1022,86 +1073,147 @@ const h2got = got.extend({request});
1022
1073
 
1023
1074
  ## Comparison
1024
1075
 
1025
- | | `got` | `request` | `node-fetch` | `axios` |
1026
- |-----------------------|:------------:|:------------:|:------------:|:------------:|
1027
- | HTTP/2 support | | ✖ | | |
1028
- | Browser support | ✖ | | ✔* | |
1029
- | Electron support | | ✖ | | |
1030
- | Promise API | ✔ | | | |
1031
- | Stream API | ✔ | | Node.js only | |
1032
- | Request cancelation | | | | |
1033
- | RFC compliant caching | | ✖ | | |
1034
- | Cookies (out-of-box) | ✔ | | | ✖ |
1035
- | Follows redirects | ✔ | | | |
1036
- | Retries on failure | | ✖ | | |
1037
- | Progress events | | | | Browser only |
1038
- | Handles gzip/deflate | ✔ | | | |
1039
- | Advanced timeouts | | ✖ | | |
1040
- | Timings | ✔ | | | ✖ |
1041
- | Errors with metadata | | ✖ | ✖ | ✔ |
1042
- | JSON mode | ✔ | | | ✔ |
1043
- | Custom defaults | ✔ | | | |
1044
- | Composable | | ✖ | | |
1045
- | Hooks | | ✖ | ✖ | ✔ |
1046
- | Issues open | ![][gio] | ![][rio] | ![][nio] | ![][aio] |
1047
- | Issues closed | ![][gic] | ![][ric] | ![][nic] | ![][aic] |
1048
- | Downloads | ![][gd] | ![][rd] | ![][nd] | ![][ad] |
1049
- | Coverage | ![][gc] | ![][rc] | ![][nc] | ![][ac] |
1050
- | Build | ![][gb] | ![][rb] | ![][nb] | ![][ab] |
1051
- | Bugs | ![][gbg] | ![][rbg] | ![][nbg] | ![][abg] |
1052
- | Dependents | ![][gdp] | ![][rdp] | ![][ndp] | ![][adp] |
1053
- | Install size | ![][gis] | ![][ris] | ![][nis] | ![][ais] |
1076
+ | | `got` | [`request`][r0] | [`node-fetch`][n0] | [`axios`][a0] | [`superagent`][s0] |
1077
+ |-----------------------|:--------------:|:---------------:|:------------------:|:---------------:|:--------------------:|
1078
+ | HTTP/2 support | | | | | ✔\*\* |
1079
+ | Browser support | | | ✔\* | | |
1080
+ | Electron support | | | | | |
1081
+ | Promise API | | | | | |
1082
+ | Stream API | | ✔ | Node.js only | | ✔ |
1083
+ | Request cancelation | | | ✔ | ✔ | |
1084
+ | RFC compliant caching | | | | | |
1085
+ | Cookies (out-of-box) | | ✔ | | | |
1086
+ | Follows redirects | | | | | |
1087
+ | Retries on failure | | | | ✖ | ✔ |
1088
+ | Progress events | | | | Browser only | ✔ |
1089
+ | Handles gzip/deflate | | | | | |
1090
+ | Advanced timeouts | | | | | |
1091
+ | Timings | | ✔ | | | |
1092
+ | Errors with metadata | | | | | |
1093
+ | JSON mode | | ✔ | | | |
1094
+ | Custom defaults | | ✔ | | | ✖ |
1095
+ | Composable | | | | ✖ | ✔ |
1096
+ | Hooks | | | | | |
1097
+ | Issues open | [![][gio]][g1] | [![][rio]][r1] | [![][nio]][n1] | [![][aio]][a1] | [![][sio]][s1] |
1098
+ | Issues closed | [![][gic]][g2] | [![][ric]][r2] | [![][nic]][n2] | [![][aic]][a2] | [![][sic]][s2] |
1099
+ | Downloads | [![][gd]][g3] | [![][rd]][r3] | [![][nd]][n3] | [![][ad]][a3] | [![][sd]][s3] |
1100
+ | Coverage | [![][gc]][g4] | [![][rc]][r4] | [![][nc]][n4] | [![][ac]][a4] | unknown |
1101
+ | Build | [![][gb]][g5] | [![][rb]][r5] | [![][nb]][n5] | [![][ab]][a5] | [![][sb]][s5] |
1102
+ | Bugs | [![][gbg]][g6] | [![][rbg]][r6] | [![][nbg]][n6] | [![][abg]][a6] | [![][sbg]][s6] |
1103
+ | Dependents | [![][gdp]][g7] | [![][rdp]][r7] | [![][ndp]][n7] | [![][adp]][a7] | [![][sdp]][s7] |
1104
+ | Install size | [![][gis]][g8] | [![][ris]][r8] | [![][nis]][n8] | [![][ais]][a8] | [![][sis]][s8] |
1054
1105
 
1055
1106
  \* It's almost API compatible with the browser `fetch` API.<br>
1107
+ \*\* Need to switch the protocol manually.<br>
1056
1108
  ❔ Experimental support.
1057
1109
 
1110
+ <!-- GITHUB -->
1111
+ [r0]: https://github.com/request/request
1112
+ [n0]: https://github.com/bitinn/node-fetch
1113
+ [a0]: https://github.com/axios/axios
1114
+ [s0]: https://github.com/visionmedia/superagent
1115
+
1058
1116
  <!-- ISSUES OPEN -->
1059
- [gio]: https://img.shields.io/github/issues/sindresorhus/got.svg
1060
- [rio]: https://img.shields.io/github/issues/request/request.svg
1061
- [nio]: https://img.shields.io/github/issues/bitinn/node-fetch.svg
1062
- [aio]: https://img.shields.io/github/issues/axios/axios.svg
1117
+ [gio]: https://badgen.net/github/open-issues/sindresorhus/got?label
1118
+ [rio]: https://badgen.net/github/open-issues/request/request?label
1119
+ [nio]: https://badgen.net/github/open-issues/bitinn/node-fetch?label
1120
+ [aio]: https://badgen.net/github/open-issues/axios/axios?label
1121
+ [sio]: https://badgen.net/github/open-issues/visionmedia/superagent?label
1122
+
1123
+ [g1]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
1124
+ [r1]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
1125
+ [n1]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
1126
+ [a1]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
1127
+ [s1]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
1063
1128
 
1064
1129
  <!-- ISSUES CLOSED -->
1065
- [gic]: https://img.shields.io/github/issues-closed/sindresorhus/got.svg
1066
- [ric]: https://img.shields.io/github/issues-closed/request/request.svg
1067
- [nic]: https://img.shields.io/github/issues-closed/bitinn/node-fetch.svg
1068
- [aic]: https://img.shields.io/github/issues-closed/axios/axios.svg
1130
+ [gic]: https://badgen.net/github/closed-issues/sindresorhus/got?label
1131
+ [ric]: https://badgen.net/github/closed-issues/request/request?label
1132
+ [nic]: https://badgen.net/github/closed-issues/bitinn/node-fetch?label
1133
+ [aic]: https://badgen.net/github/closed-issues/axios/axios?label
1134
+ [sic]: https://badgen.net/github/closed-issues/visionmedia/superagent?label
1135
+
1136
+ [g2]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
1137
+ [r2]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
1138
+ [n2]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
1139
+ [a2]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
1140
+ [s2]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
1069
1141
 
1070
1142
  <!-- DOWNLOADS -->
1071
- [gd]: https://img.shields.io/npm/dm/got.svg
1072
- [rd]: https://img.shields.io/npm/dm/request.svg
1073
- [nd]: https://img.shields.io/npm/dm/node-fetch.svg
1074
- [ad]: https://img.shields.io/npm/dm/axios.svg
1143
+ [gd]: https://badgen.net/npm/dm/got?label
1144
+ [rd]: https://badgen.net/npm/dm/request?label
1145
+ [nd]: https://badgen.net/npm/dm/node-fetch?label
1146
+ [ad]: https://badgen.net/npm/dm/axios?label
1147
+ [sd]: https://badgen.net/npm/dm/superagent?label
1148
+
1149
+ [g3]: https://www.npmjs.com/package/got
1150
+ [r3]: https://www.npmjs.com/package/request
1151
+ [n3]: https://www.npmjs.com/package/node-fetch
1152
+ [a3]: https://www.npmjs.com/package/axios
1153
+ [s3]: https://www.npmjs.com/package/superagent
1075
1154
 
1076
1155
  <!-- COVERAGE -->
1077
- [gc]: https://coveralls.io/repos/github/sindresorhus/got/badge.svg?branch=master
1078
- [rc]: https://coveralls.io/repos/github/request/request/badge.svg?branch=master
1079
- [nc]: https://coveralls.io/repos/github/bitinn/node-fetch/badge.svg?branch=master
1080
- [ac]: https://coveralls.io/repos/github/mzabriskie/axios/badge.svg?branch=master
1156
+ [gc]: https://badgen.net/coveralls/c/github/sindresorhus/got?label
1157
+ [rc]: https://badgen.net/coveralls/c/github/request/request?label
1158
+ [nc]: https://badgen.net/coveralls/c/github/bitinn/node-fetch?label
1159
+ [ac]: https://badgen.net/coveralls/c/github/mzabriskie/axios?label
1160
+
1161
+ [g4]: https://coveralls.io/github/sindresorhus/got
1162
+ [r4]: https://coveralls.io/github/request/request
1163
+ [n4]: https://coveralls.io/github/bitinn/node-fetch
1164
+ [a4]: https://coveralls.io/github/mzabriskie/axios
1081
1165
 
1082
1166
  <!-- BUILD -->
1083
- [gb]: https://travis-ci.org/sindresorhus/got.svg?branch=master
1084
- [rb]: https://travis-ci.org/request/request.svg?branch=master
1085
- [nb]: https://travis-ci.org/bitinn/node-fetch.svg?branch=master
1086
- [ab]: https://travis-ci.org/axios/axios.svg?branch=master
1167
+ [gb]: https://badgen.net/travis/sindresorhus/got?label
1168
+ [rb]: https://badgen.net/travis/request/request?label
1169
+ [nb]: https://badgen.net/travis/bitinn/node-fetch?label
1170
+ [ab]: https://badgen.net/travis/axios/axios?label
1171
+ [sb]: https://badgen.net/travis/visionmedia/superagent?label
1172
+
1173
+ [g5]: https://travis-ci.org/sindresorhus/got
1174
+ [r5]: https://travis-ci.org/request/request
1175
+ [n5]: https://travis-ci.org/bitinn/node-fetch
1176
+ [a5]: https://travis-ci.org/axios/axios
1177
+ [s5]: https://travis-ci.org/visionmedia/superagent
1087
1178
 
1088
1179
  <!-- BUGS -->
1089
- [gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open
1090
- [rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open
1091
- [nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open
1092
- [abg]: https://badgen.net/github/label-issues/axios/axios/bug/open
1180
+ [gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
1181
+ [rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open?label
1182
+ [nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open?label
1183
+ [abg]: https://badgen.net/github/label-issues/axios/axios/bug/open?label
1184
+ [sbg]: https://badgen.net/github/label-issues/visionmedia/superagent/Bug/open?label
1185
+
1186
+ [g6]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
1187
+ [r6]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A"Needs+investigation"
1188
+ [n6]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
1189
+ [a6]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
1190
+ [s6]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3ABug
1093
1191
 
1094
1192
  <!-- DEPENDENTS -->
1095
- [gdp]: https://badgen.net/npm/dependents/got
1096
- [rdp]: https://badgen.net/npm/dependents/request
1097
- [ndp]: https://badgen.net/npm/dependents/node-fetch
1098
- [adp]: https://badgen.net/npm/dependents/axios
1193
+ [gdp]: https://badgen.net/npm/dependents/got?label
1194
+ [rdp]: https://badgen.net/npm/dependents/request?label
1195
+ [ndp]: https://badgen.net/npm/dependents/node-fetch?label
1196
+ [adp]: https://badgen.net/npm/dependents/axios?label
1197
+ [sdp]: https://badgen.net/npm/dependents/superagent?label
1198
+
1199
+ [g7]: https://www.npmjs.com/package/got?activeTab=dependents
1200
+ [r7]: https://www.npmjs.com/package/request?activeTab=dependents
1201
+ [n7]: https://www.npmjs.com/package/node-fetch?activeTab=dependents
1202
+ [a7]: https://www.npmjs.com/package/axios?activeTab=dependents
1203
+ [s7]: https://www.npmjs.com/package/visionmedia?activeTab=dependents
1099
1204
 
1100
1205
  <!-- INSTALL SIZE -->
1101
- [gis]: https://packagephobia.now.sh/badge?p=got
1102
- [ris]: https://packagephobia.now.sh/badge?p=request
1103
- [nis]: https://packagephobia.now.sh/badge?p=node-fetch
1104
- [ais]: https://packagephobia.now.sh/badge?p=axios
1206
+ [gis]: https://badgen.net/packagephobia/install/got?label
1207
+ [ris]: https://badgen.net/packagephobia/install/request?label
1208
+ [nis]: https://badgen.net/packagephobia/install/node-fetch?label
1209
+ [ais]: https://badgen.net/packagephobia/install/axios?label
1210
+ [sis]: https://badgen.net/packagephobia/install/superagent?label
1211
+
1212
+ [g8]: https://packagephobia.now.sh/result?p=got
1213
+ [r8]: https://packagephobia.now.sh/result?p=request
1214
+ [n8]: https://packagephobia.now.sh/result?p=node-fetch
1215
+ [a8]: https://packagephobia.now.sh/result?p=axios
1216
+ [s8]: https://packagephobia.now.sh/result?p=superagent
1105
1217
 
1106
1218
 
1107
1219
  ## Related
@@ -81,6 +81,7 @@ const asPromise = options => {
81
81
 
82
82
  resolve(response);
83
83
  }
84
+
84
85
  return;
85
86
  }
86
87
 
@@ -83,6 +83,7 @@ module.exports = options => {
83
83
 
84
84
  return result;
85
85
  };
86
+
86
87
  proxy.unpipe = stream => {
87
88
  piped.delete(stream);
88
89
  return unpipe(stream);
package/source/errors.js CHANGED
@@ -5,7 +5,7 @@ const PCancelable = require('p-cancelable');
5
5
  const is = require('@sindresorhus/is');
6
6
 
7
7
  class GotError extends Error {
8
- constructor(message, error, opts) {
8
+ constructor(message, error, options) {
9
9
  super(message);
10
10
  Error.captureStackTrace(this, this.constructor);
11
11
  this.name = 'GotError';
@@ -15,13 +15,14 @@ class GotError extends Error {
15
15
  }
16
16
 
17
17
  Object.assign(this, {
18
- host: opts.host,
19
- hostname: opts.hostname,
20
- method: opts.method,
21
- path: opts.path,
22
- socketPath: opts.socketPath,
23
- protocol: opts.protocol,
24
- url: opts.href
18
+ host: options.host,
19
+ hostname: options.hostname,
20
+ method: options.method,
21
+ path: options.path,
22
+ socketPath: options.socketPath,
23
+ protocol: options.protocol,
24
+ url: options.href,
25
+ gotOptions: options
25
26
  });
26
27
  }
27
28
  }
@@ -29,29 +30,29 @@ class GotError extends Error {
29
30
  module.exports.GotError = GotError;
30
31
 
31
32
  module.exports.CacheError = class extends GotError {
32
- constructor(error, opts) {
33
- super(error.message, error, opts);
33
+ constructor(error, options) {
34
+ super(error.message, error, options);
34
35
  this.name = 'CacheError';
35
36
  }
36
37
  };
37
38
 
38
39
  module.exports.RequestError = class extends GotError {
39
- constructor(error, opts) {
40
- super(error.message, error, opts);
40
+ constructor(error, options) {
41
+ super(error.message, error, options);
41
42
  this.name = 'RequestError';
42
43
  }
43
44
  };
44
45
 
45
46
  module.exports.ReadError = class extends GotError {
46
- constructor(error, opts) {
47
- super(error.message, error, opts);
47
+ constructor(error, options) {
48
+ super(error.message, error, options);
48
49
  this.name = 'ReadError';
49
50
  }
50
51
  };
51
52
 
52
53
  module.exports.ParseError = class extends GotError {
53
- constructor(error, statusCode, opts, data) {
54
- super(`${error.message} in "${urlLib.format(opts)}": \n${data.slice(0, 77)}...`, error, opts);
54
+ constructor(error, statusCode, options, data) {
55
+ super(`${error.message} in "${urlLib.format(options)}": \n${data.slice(0, 77)}...`, error, options);
55
56
  this.name = 'ParseError';
56
57
  this.statusCode = statusCode;
57
58
  this.statusMessage = http.STATUS_CODES[this.statusCode];
@@ -59,7 +60,7 @@ module.exports.ParseError = class extends GotError {
59
60
  };
60
61
 
61
62
  module.exports.HTTPError = class extends GotError {
62
- constructor(response, opts) {
63
+ constructor(response, options) {
63
64
  const {statusCode} = response;
64
65
  let {statusMessage} = response;
65
66
 
@@ -68,7 +69,8 @@ module.exports.HTTPError = class extends GotError {
68
69
  } else {
69
70
  statusMessage = http.STATUS_CODES[statusCode];
70
71
  }
71
- super(`Response code ${statusCode} (${statusMessage})`, {}, opts);
72
+
73
+ super(`Response code ${statusCode} (${statusMessage})`, {}, options);
72
74
  this.name = 'HTTPError';
73
75
  this.statusCode = statusCode;
74
76
  this.statusMessage = statusMessage;
@@ -78,8 +80,8 @@ module.exports.HTTPError = class extends GotError {
78
80
  };
79
81
 
80
82
  module.exports.MaxRedirectsError = class extends GotError {
81
- constructor(statusCode, redirectUrls, opts) {
82
- super('Redirected 10 times. Aborting.', {}, opts);
83
+ constructor(statusCode, redirectUrls, options) {
84
+ super('Redirected 10 times. Aborting.', {}, options);
83
85
  this.name = 'MaxRedirectsError';
84
86
  this.statusCode = statusCode;
85
87
  this.statusMessage = http.STATUS_CODES[this.statusCode];
@@ -88,15 +90,15 @@ module.exports.MaxRedirectsError = class extends GotError {
88
90
  };
89
91
 
90
92
  module.exports.UnsupportedProtocolError = class extends GotError {
91
- constructor(opts) {
92
- super(`Unsupported protocol "${opts.protocol}"`, {}, opts);
93
+ constructor(options) {
94
+ super(`Unsupported protocol "${options.protocol}"`, {}, options);
93
95
  this.name = 'UnsupportedProtocolError';
94
96
  }
95
97
  };
96
98
 
97
99
  module.exports.TimeoutError = class extends GotError {
98
- constructor(error, opts) {
99
- super(error.message, {code: 'ETIMEDOUT'}, opts);
100
+ constructor(error, options) {
101
+ super(error.message, {code: 'ETIMEDOUT'}, options);
100
102
  this.name = 'TimeoutError';
101
103
  this.event = error.event;
102
104
  }
package/source/index.js CHANGED
@@ -22,6 +22,16 @@ const defaults = {
22
22
  502,
23
23
  503,
24
24
  504
25
+ ],
26
+ errorCodes: [
27
+ 'ETIMEDOUT',
28
+ 'ECONNRESET',
29
+ 'EADDRINUSE',
30
+ 'ECONNREFUSED',
31
+ 'EPIPE',
32
+ 'ENOTFOUND',
33
+ 'ENETUNREACH',
34
+ 'EAI_AGAIN'
25
35
  ]
26
36
  },
27
37
  headers: {
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  module.exports = [
4
+ 'beforeError',
5
+ 'init',
4
6
  'beforeRequest',
5
7
  'beforeRedirect',
6
8
  'beforeRetry',
@@ -4,7 +4,6 @@ const urlLib = require('url');
4
4
  const is = require('@sindresorhus/is');
5
5
  const urlParseLax = require('url-parse-lax');
6
6
  const lowercaseKeys = require('lowercase-keys');
7
- const isRetryOnNetworkErrorAllowed = require('./utils/is-retry-on-network-error-allowed');
8
7
  const urlToOptions = require('./utils/url-to-options');
9
8
  const isFormData = require('./utils/is-form-data');
10
9
  const merge = require('./merge');
@@ -12,8 +11,15 @@ const knownHookEvents = require('./known-hook-events');
12
11
 
13
12
  const retryAfterStatusCodes = new Set([413, 429, 503]);
14
13
 
15
- // `preNormalize` handles static things (lowercasing headers; normalizing baseUrl, timeout, retry)
16
- // While `normalize` does `preNormalize` + handles things which need to be reworked when user changes them
14
+ // `preNormalize` handles static options (e.g. headers).
15
+ // For example, when you create a custom instance and make a request
16
+ // with no static changes, they won't be normalized again.
17
+ //
18
+ // `normalize` operates on dynamic options - they cannot be saved.
19
+ // For example, `body` is everytime different per request.
20
+ // When it's done normalizing the new options, it performs merge()
21
+ // on the prenormalized options and the normalized ones.
22
+
17
23
  const preNormalize = (options, defaults) => {
18
24
  if (is.nullOrUndefined(options.headers)) {
19
25
  options.headers = {};
@@ -50,13 +56,15 @@ const preNormalize = (options, defaults) => {
50
56
  } else if (is.object(options.timeout)) {
51
57
  options.gotTimeout = options.timeout;
52
58
  }
59
+
53
60
  delete options.timeout;
54
61
 
55
62
  const {retry} = options;
56
63
  options.retry = {
57
64
  retries: 0,
58
65
  methods: [],
59
- statusCodes: []
66
+ statusCodes: [],
67
+ errorCodes: []
60
68
  };
61
69
 
62
70
  if (is.nonEmptyObject(defaults) && retry !== false) {
@@ -83,6 +91,10 @@ const preNormalize = (options, defaults) => {
83
91
  options.retry.statusCodes = new Set(options.retry.statusCodes);
84
92
  }
85
93
 
94
+ if (is.array(options.retry.errorCodes)) {
95
+ options.retry.errorCodes = new Set(options.retry.errorCodes);
96
+ }
97
+
86
98
  return options;
87
99
  };
88
100
 
@@ -96,7 +108,7 @@ const normalize = (url, options, defaults) => {
96
108
  if (defaults) {
97
109
  options = merge({}, defaults.options, options ? preNormalize(options, defaults.options) : {});
98
110
  } else {
99
- options = merge({}, options ? preNormalize(options) : {});
111
+ options = merge({}, preNormalize(options));
100
112
  }
101
113
 
102
114
  if (!is.string(url) && !is.object(url)) {
@@ -112,11 +124,7 @@ const normalize = (url, options, defaults) => {
112
124
  url = urlToOptions(new URL(url, options.baseUrl));
113
125
  } else {
114
126
  url = url.replace(/^unix:/, 'http://$&');
115
-
116
127
  url = urlParseLax(url);
117
- if (url.auth) {
118
- throw new Error('Basic authentication must be done with the `auth` option');
119
- }
120
128
  }
121
129
  } else if (is(url) === 'URL') {
122
130
  url = urlToOptions(url);
@@ -125,6 +133,14 @@ const normalize = (url, options, defaults) => {
125
133
  // Override both null/undefined with default protocol
126
134
  options = merge({path: ''}, url, {protocol: url.protocol || 'https:'}, options);
127
135
 
136
+ for (const hook of options.hooks.init) {
137
+ const called = hook(options);
138
+
139
+ if (is.promise(called)) {
140
+ throw new TypeError('The `init` hook must be a synchronous function');
141
+ }
142
+ }
143
+
128
144
  const {baseUrl} = options;
129
145
  Object.defineProperty(options, 'baseUrl', {
130
146
  set: () => {
@@ -138,6 +154,7 @@ const normalize = (url, options, defaults) => {
138
154
  if (!is.string(query)) {
139
155
  options.query = (new URLSearchParams(query)).toString();
140
156
  }
157
+
141
158
  options.path = `${options.path.split('?')[0]}?${options.query}`;
142
159
  delete options.query;
143
160
  }
@@ -210,29 +227,27 @@ const normalize = (url, options, defaults) => {
210
227
  return 0;
211
228
  }
212
229
 
213
- if (error !== null) {
214
- if (!isRetryOnNetworkErrorAllowed(error) && (!options.retry.methods.has(error.method) || !options.retry.statusCodes.has(error.statusCode))) {
215
- return 0;
216
- }
217
-
218
- if (Reflect.has(error, 'headers') && Reflect.has(error.headers, 'retry-after') && retryAfterStatusCodes.has(error.statusCode)) {
219
- let after = Number(error.headers['retry-after']);
220
- if (is.nan(after)) {
221
- after = Date.parse(error.headers['retry-after']) - Date.now();
222
- } else {
223
- after *= 1000;
224
- }
225
-
226
- if (after > options.retry.maxRetryAfter) {
227
- return 0;
228
- }
230
+ if ((!error || !options.retry.errorCodes.has(error.code)) && (!options.retry.methods.has(error.method) || !options.retry.statusCodes.has(error.statusCode))) {
231
+ return 0;
232
+ }
229
233
 
230
- return after;
234
+ if (Reflect.has(error, 'headers') && Reflect.has(error.headers, 'retry-after') && retryAfterStatusCodes.has(error.statusCode)) {
235
+ let after = Number(error.headers['retry-after']);
236
+ if (is.nan(after)) {
237
+ after = Date.parse(error.headers['retry-after']) - Date.now();
238
+ } else {
239
+ after *= 1000;
231
240
  }
232
241
 
233
- if (error.statusCode === 413) {
242
+ if (after > options.retry.maxRetryAfter) {
234
243
  return 0;
235
244
  }
245
+
246
+ return after;
247
+ }
248
+
249
+ if (error.statusCode === 413) {
250
+ return 0;
236
251
  }
237
252
 
238
253
  const noise = Math.random() * 100;
@@ -33,6 +33,19 @@ module.exports = (options, input) => {
33
33
  const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
34
34
  const agents = is.object(options.agent) ? options.agent : null;
35
35
 
36
+ const emitError = async error => {
37
+ try {
38
+ for (const hook of options.hooks.beforeError) {
39
+ // eslint-disable-next-line no-await-in-loop
40
+ error = await hook(error);
41
+ }
42
+
43
+ emitter.emit('error', error);
44
+ } catch (error2) {
45
+ emitter.emit('error', error2);
46
+ }
47
+ };
48
+
36
49
  const get = async options => {
37
50
  const currentUrl = redirectString || requestUrl;
38
51
 
@@ -92,6 +105,9 @@ module.exports = (options, input) => {
92
105
  response.retryCount = retryCount;
93
106
  response.timings = timings;
94
107
  response.redirectUrls = redirects;
108
+ response.request = {
109
+ gotOptions: options
110
+ };
95
111
 
96
112
  const rawCookies = response.headers['set-cookie'];
97
113
  if (options.cookieJar && rawCookies) {
@@ -119,26 +135,26 @@ module.exports = (options, input) => {
119
135
 
120
136
  redirects.push(redirectString);
121
137
 
122
- const redirectOpts = {
138
+ const redirectOptions = {
123
139
  ...options,
124
140
  ...urlToOptions(redirectURL)
125
141
  };
126
142
 
127
143
  for (const hook of options.hooks.beforeRedirect) {
128
144
  // eslint-disable-next-line no-await-in-loop
129
- await hook(redirectOpts);
145
+ await hook(redirectOptions);
130
146
  }
131
147
 
132
- emitter.emit('redirect', response, redirectOpts);
148
+ emitter.emit('redirect', response, redirectOptions);
133
149
 
134
- await get(redirectOpts);
150
+ await get(redirectOptions);
135
151
  return;
136
152
  }
137
153
  }
138
154
 
139
155
  getResponse(response, options, emitter);
140
156
  } catch (error) {
141
- emitter.emit('error', error);
157
+ emitError(error);
142
158
  }
143
159
  };
144
160
 
@@ -163,7 +179,7 @@ module.exports = (options, input) => {
163
179
  }
164
180
 
165
181
  if (emitter.retry(error) === false) {
166
- emitter.emit('error', error);
182
+ emitError(error);
167
183
  }
168
184
  });
169
185
 
@@ -195,29 +211,29 @@ module.exports = (options, input) => {
195
211
  request.end(uploadComplete);
196
212
  }
197
213
  } catch (error) {
198
- emitter.emit('error', new RequestError(error, options));
214
+ emitError(new RequestError(error, options));
199
215
  }
200
216
  };
201
217
 
202
218
  if (options.cache) {
203
219
  const cacheableRequest = new CacheableRequest(fn.request, options.cache);
204
- const cacheReq = cacheableRequest(options, handleResponse);
220
+ const cacheRequest = cacheableRequest(options, handleResponse);
205
221
 
206
- cacheReq.once('error', error => {
222
+ cacheRequest.once('error', error => {
207
223
  if (error instanceof CacheableRequest.RequestError) {
208
- emitter.emit('error', new RequestError(error, options));
224
+ emitError(new RequestError(error, options));
209
225
  } else {
210
- emitter.emit('error', new CacheError(error, options));
226
+ emitError(new CacheError(error, options));
211
227
  }
212
228
  });
213
229
 
214
- cacheReq.once('request', handleRequest);
230
+ cacheRequest.once('request', handleRequest);
215
231
  } else {
216
232
  // Catches errors thrown by calling fn.request(...)
217
233
  try {
218
234
  handleRequest(fn.request(options, handleResponse));
219
235
  } catch (error) {
220
- emitter.emit('error', new RequestError(error, options));
236
+ emitError(new RequestError(error, options));
221
237
  }
222
238
  }
223
239
  };
@@ -228,7 +244,7 @@ module.exports = (options, input) => {
228
244
  try {
229
245
  backoff = options.retry.retries(++retryCount, error);
230
246
  } catch (error2) {
231
- emitter.emit('error', error2);
247
+ emitError(error2);
232
248
  return;
233
249
  }
234
250
 
@@ -242,7 +258,7 @@ module.exports = (options, input) => {
242
258
 
243
259
  await get(options);
244
260
  } catch (error) {
245
- emitter.emit('error', error);
261
+ emitError(error);
246
262
  }
247
263
  };
248
264
 
@@ -288,7 +304,7 @@ module.exports = (options, input) => {
288
304
 
289
305
  await get(options);
290
306
  } catch (error) {
291
- emitter.emit('error', error);
307
+ emitError(error);
292
308
  }
293
309
  });
294
310
 
@@ -82,9 +82,16 @@ module.exports = (request, delays, options) => {
82
82
  }
83
83
 
84
84
  if (delays.socket !== undefined) {
85
- request.setTimeout(delays.socket, () => {
85
+ const socketTimeoutHandler = () => {
86
86
  timeoutHandler(delays.socket, 'socket');
87
- });
87
+ };
88
+
89
+ request.setTimeout(delays.socket, socketTimeoutHandler);
90
+
91
+ // `request.setTimeout(0)` causes a memory leak.
92
+ // We can just remove the listener and forget about the timer - it's unreffed.
93
+ // See https://github.com/sindresorhus/got/issues/690
94
+ cancelers.push(() => request.removeListener('timeout', socketTimeoutHandler));
88
95
  }
89
96
 
90
97
  if (delays.lookup !== undefined && !request.socketPath && !net.isIP(hostname || host)) {
@@ -1,20 +0,0 @@
1
- 'use strict';
2
-
3
- const WHITELIST = new Set([
4
- 'ETIMEDOUT',
5
- 'ECONNRESET',
6
- 'EADDRINUSE',
7
- 'ECONNREFUSED',
8
- 'EPIPE',
9
- 'ENOTFOUND',
10
- 'ENETUNREACH',
11
- 'EAI_AGAIN'
12
- ]);
13
-
14
- module.exports = error => {
15
- if (error && WHITELIST.has(error.code)) {
16
- return true;
17
- }
18
-
19
- return false;
20
- };