From b3f456e795f9a7b459efa8e774061609a21c74a3 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 4 Jan 2021 07:34:09 +1000 Subject: [PATCH 1/9] Described ky.stop in readme --- readme.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index fa970c3f..6aebbae2 100644 --- a/readme.md +++ b/readme.md @@ -256,7 +256,9 @@ Default: `[]` This hook enables you to modify the request right before retry. Ky will make no further changes to the request after this. The hook function receives an object with the normalized request and options, an error instance, and the retry count. You could, for example, modify `request.headers` here. -If the request received a response, it will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. +If the request received a response, `error` will be an `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In this case `error` will not be an instance of `HTTPError` though. + +You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of `beforeRetry` hooks will be fired if you `throw error`. Another way to do it is to return the [`ky.stop`](#ky.stop) symbol, but it has important caveats which are described in the dedicated section. You should only use it if you are absolutely sure that `throw error` doesn't work for you. ```js import ky from 'ky'; @@ -466,7 +468,13 @@ The error thrown when the request times out. ### ky.stop -A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. +A special `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. + +#### Warning + +Consider throwing `error` in `beforeRetry` hook before using `ky.stop`. If `ky.stop` is returned, you will **not** get the `response` object even if it was received but had `4xx-5xx` status. It is also incompatible with shortcut methods, such as `.json` or `.text`. Since no response is returned, these are unable to call the native methods to retrieve response body. + +A valid use case for `ky.stop` is to prevent retries when making requests for side effects, where returned data is not important. For example, logging client activity to the server. If you are going to use the body of the response in any way, you probably don't want to use `ky.stop`. ```js import ky from 'ky'; From 254226b93886af5a1c97ed19340572efa2d72dd3 Mon Sep 17 00:00:00 2001 From: ialexi-bl <44489753+ialexi-bl@users.noreply.github.com> Date: Mon, 4 Jan 2021 15:37:57 +1000 Subject: [PATCH 2/9] Fixed a typo --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6aebbae2..b8d8c2a9 100644 --- a/readme.md +++ b/readme.md @@ -258,7 +258,7 @@ This hook enables you to modify the request right before retry. Ky will make no If the request received a response, `error` will be an `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In this case `error` will not be an instance of `HTTPError` though. -You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of `beforeRetry` hooks will be fired if you `throw error`. Another way to do it is to return the [`ky.stop`](#ky.stop) symbol, but it has important caveats which are described in the dedicated section. You should only use it if you are absolutely sure that `throw error` doesn't work for you. +You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of `beforeRetry` hooks will not be fired if you `throw error`. Another way to do it is to return the [`ky.stop`](#ky.stop) symbol, but it has important caveats which are described in the dedicated section. You should only use it if you are absolutely sure that `throw error` doesn't work for you. ```js import ky from 'ky'; From 47cc165a7fa05b3042657c211bf5d012e4b22ebe Mon Sep 17 00:00:00 2001 From: ialexi-bl <44489753+ialexi-bl@users.noreply.github.com> Date: Mon, 4 Jan 2021 15:41:01 +1000 Subject: [PATCH 3/9] Added description of ky.stop caveats in code --- readme.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index b8d8c2a9..2bf84cfa 100644 --- a/readme.md +++ b/readme.md @@ -480,18 +480,22 @@ A valid use case for `ky.stop` is to prevent retries when making requests for si import ky from 'ky'; (async () => { - await ky('https://example.com', { + const options = { hooks: { beforeRetry: [ async ({request, options, error, retryCount}) => { - const shouldStopRetry = await ky('https://example.com/api'); - if (shouldStopRetry) { - return ky.stop; - } + const token = await ky('https://example.com/refresh-token'); + request.headers.set('Authorization', `token ${token}`); } ] } - }); + } + + // If `ky.stop` is returned from `beforeRetry` hook, `response + // will be `undefined` here + const response = await ky('https://example.com', options); + // This is not allowed + const text = await ky('https://example.com', options).text() })(); ``` From cf5ad2f91b259cad29875b28ed839f5238c59d84 Mon Sep 17 00:00:00 2001 From: Seth Holladay Date: Mon, 4 Jan 2021 02:24:24 -0500 Subject: [PATCH 4/9] Update readme.md --- readme.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index 2bf84cfa..a6bbfc16 100644 --- a/readme.md +++ b/readme.md @@ -468,13 +468,11 @@ The error thrown when the request times out. ### ky.stop -A special `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. +A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. -#### Warning +Note: This aborts _successfully_ and Ky will return with an `undefined` response. If you use `ky.stop`, be sure to check for a response first before accessing any properties on it or use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining). It is also incompatible with body methods, such as `.json()` or `.text()`, because there is no response to parse. In general, we recommend to `throw error` instead of `return ky.stop`, as that will abort _unsuccesfully_ and Ky will throw, which avoids these limitations. -Consider throwing `error` in `beforeRetry` hook before using `ky.stop`. If `ky.stop` is returned, you will **not** get the `response` object even if it was received but had `4xx-5xx` status. It is also incompatible with shortcut methods, such as `.json` or `.text`. Since no response is returned, these are unable to call the native methods to retrieve response body. - -A valid use case for `ky.stop` is to prevent retries when making requests for side effects, where returned data is not important. For example, logging client activity to the server. If you are going to use the body of the response in any way, you probably don't want to use `ky.stop`. +A valid use case for `ky.stop` is to prevent retries when making requests for side effects, where returned data is not important. For example, logging client activity to the server. ```js import ky from 'ky'; @@ -491,11 +489,10 @@ import ky from 'ky'; } } - // If `ky.stop` is returned from `beforeRetry` hook, `response - // will be `undefined` here - const response = await ky('https://example.com', options); - // This is not allowed - const text = await ky('https://example.com', options).text() + await ky.post('https://example.com', options); + + // Using .text() or other body methods is not suppported + const text = await ky('https://example.com', options).text(); })(); ``` From c64968ecb60623b36ac30b96f816c709437a528b Mon Sep 17 00:00:00 2001 From: Seth Holladay Date: Mon, 4 Jan 2021 02:38:22 -0500 Subject: [PATCH 5/9] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a6bbfc16..e66dabec 100644 --- a/readme.md +++ b/readme.md @@ -256,9 +256,9 @@ Default: `[]` This hook enables you to modify the request right before retry. Ky will make no further changes to the request after this. The hook function receives an object with the normalized request and options, an error instance, and the retry count. You could, for example, modify `request.headers` here. -If the request received a response, `error` will be an `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In this case `error` will not be an instance of `HTTPError` though. +If the request received a response, `error` will be an `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, `error` will not be an instance of `HTTPError`, though. -You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of `beforeRetry` hooks will not be fired if you `throw error`. Another way to do it is to return the [`ky.stop`](#ky.stop) symbol, but it has important caveats which are described in the dedicated section. You should only use it if you are absolutely sure that `throw error` doesn't work for you. +You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of the `beforeRetry` hooks will not be called if you `throw error`. Alternatively, you can return the [`ky.stop`](#ky.stop) symbol to do the same thing but without throwing (this has some limitations, see `ky.stop` docs for details). ```js import ky from 'ky'; From 85c381596f04f7200e565c5d5435133ff4b360fe Mon Sep 17 00:00:00 2001 From: ialexi-bl <44489753+ialexi-bl@users.noreply.github.com> Date: Mon, 4 Jan 2021 19:25:47 +1000 Subject: [PATCH 6/9] Update readme.md --- readme.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index e66dabec..054643f3 100644 --- a/readme.md +++ b/readme.md @@ -256,9 +256,9 @@ Default: `[]` This hook enables you to modify the request right before retry. Ky will make no further changes to the request after this. The hook function receives an object with the normalized request and options, an error instance, and the retry count. You could, for example, modify `request.headers` here. -If the request received a response, `error` will be an `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, `error` will not be an instance of `HTTPError`, though. +If the request received a response, the error will be of type `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, the error will not be an instance of `HTTPError`. -You can prevent Ky from retrying the request by throwing `error`. Ky will not handle it in any way, this error will be propagated to the request initiator. The rest of the `beforeRetry` hooks will not be called if you `throw error`. Alternatively, you can return the [`ky.stop`](#ky.stop) symbol to do the same thing but without throwing (this has some limitations, see `ky.stop` docs for details). +You can prevent Ky from retrying the request by throwing an error. Ky will not handle it in any way and the error will be propagated to the request initiator. The rest of the `beforeRetry` hooks will not be called in this case. Alternatively, you can return the [`ky.stop`](#ky.stop) symbol to do the same thing but without propagating an error (this has some limitations, see `ky.stop` docs for details). ```js import ky from 'ky'; @@ -470,9 +470,9 @@ The error thrown when the request times out. A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. -Note: This aborts _successfully_ and Ky will return with an `undefined` response. If you use `ky.stop`, be sure to check for a response first before accessing any properties on it or use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining). It is also incompatible with body methods, such as `.json()` or `.text()`, because there is no response to parse. In general, we recommend to `throw error` instead of `return ky.stop`, as that will abort _unsuccesfully_ and Ky will throw, which avoids these limitations. +Note: Returning this symbol makes Ky abort and return with an `undefined` response. Be sure to check for a response before accessing any properties on it or use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining). It is also incompatible with body methods, such as `.json()` or `.text()`, because there is no response to parse. In general, we recommend throwing an error instead of returning this symbol, as that will cause Ky to abort and then throw, which avoids these limitations. -A valid use case for `ky.stop` is to prevent retries when making requests for side effects, where returned data is not important. For example, logging client activity to the server. +A valid use-case for `ky.stop` is to prevent retries when making requests for side effects, where the returned data is not important. For example, logging client activity to the server. ```js import ky from 'ky'; @@ -482,14 +482,17 @@ import ky from 'ky'; hooks: { beforeRetry: [ async ({request, options, error, retryCount}) => { - const token = await ky('https://example.com/refresh-token'); - request.headers.set('Authorization', `token ${token}`); + const shouldStopRetry = await ky('https://example.com/api'); + if (shouldStopRetry) { + return ky.stop; + } } ] } - } - - await ky.post('https://example.com', options); + }; + + // Note that response will be undefined in case `ky.stop` is returned + const response = await ky.post('https://example.com', options); // Using .text() or other body methods is not suppported const text = await ky('https://example.com', options).text(); From a5ea89713af997f9c0f45cd26c07b48906ec41e2 Mon Sep 17 00:00:00 2001 From: ialexi-bl <44489753+ialexi-bl@users.noreply.github.com> Date: Mon, 4 Jan 2021 19:34:32 +1000 Subject: [PATCH 7/9] Update index.d.ts --- index.d.ts | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index b4f5c13b..abc112ba 100644 --- a/index.d.ts +++ b/index.d.ts @@ -47,8 +47,10 @@ export interface Hooks { /** This hook enables you to modify the request right before retry. Ky will make no further changes to the request after this. The hook function receives an object with the normalized request and options, an error instance, and the retry count. You could, for example, modify `request.headers` here. - - If the request received a response, it will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. + + If the request received a response, the error will be of type `HTTPError` and the `Response` object will be available at `error.response`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, the error will not be an instance of `HTTPError`. + + You can prevent Ky from retrying the request by throwing an error. Ky will not handle it in any way and the error will be propagated to the request initiator. The rest of the `beforeRetry` hooks will not be called in this case. Alternatively, you can return the [`ky.stop`](#ky.stop) symbol to do the same thing but without propagating an error (this has some limitations, see `ky.stop` docs for details). @example ``` @@ -512,15 +514,19 @@ declare const ky: { extend: (defaultOptions: Options) => typeof ky; /** - A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. - This will also short circuit the remaining `beforeRetry` hooks. + A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks. + + Note: Returning this symbol makes Ky abort and return with an `undefined` response. Be sure to check for a response before accessing any properties on it or use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining). It is also incompatible with body methods, such as `.json()` or `.text()`, because there is no response to parse. In general, we recommend throwing an error instead of returning this symbol, as that will cause Ky to abort and then throw, which avoids these limitations. + + A valid use-case for `ky.stop` is to prevent retries when making requests for side effects, where the returned data is not important. For example, logging client activity to the server. + @example ``` import ky from 'ky'; - + (async () => { - await ky('https://example.com', { + const options = { hooks: { beforeRetry: [ async ({request, options, error, retryCount}) => { @@ -531,7 +537,13 @@ declare const ky: { } ] } - }); + }; + + // Note that response will be undefined in case `ky.stop` is returned + const response = await ky.post('https://example.com', options); + + // Using .text() or other body methods is not suppported + const text = await ky('https://example.com', options).text(); })(); ``` */ From 3273a909e1bd15f23c1966169e311931717d67be Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 8 Jan 2021 15:11:54 +0700 Subject: [PATCH 8/9] Update index.d.ts --- index.d.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index abc112ba..e9c9f23f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -520,11 +520,10 @@ declare const ky: { A valid use-case for `ky.stop` is to prevent retries when making requests for side effects, where the returned data is not important. For example, logging client activity to the server. - @example ``` import ky from 'ky'; - + (async () => { const options = { hooks: { @@ -539,10 +538,10 @@ declare const ky: { } }; - // Note that response will be undefined in case `ky.stop` is returned + // Note that response will be `undefined` in case `ky.stop` is returned. const response = await ky.post('https://example.com', options); - // Using .text() or other body methods is not suppported + // Using `.text()` or other body methods is not suppported. const text = await ky('https://example.com', options).text(); })(); ``` From d17572ac1d2ac2d9f6b77962406e9c6fa982517e Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 8 Jan 2021 15:12:49 +0700 Subject: [PATCH 9/9] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 054643f3..67dfd979 100644 --- a/readme.md +++ b/readme.md @@ -491,10 +491,10 @@ import ky from 'ky'; } }; - // Note that response will be undefined in case `ky.stop` is returned + // Note that response will be `undefined` in case `ky.stop` is returned. const response = await ky.post('https://example.com', options); - // Using .text() or other body methods is not suppported + // Using `.text()` or other body methods is not suppported. const text = await ky('https://example.com', options).text(); })(); ```