You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: readme.md
+83Lines changed: 83 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -489,6 +489,8 @@ Default: `[]`
489
489
490
490
This hook enables you to read and optionally modify the response. The hook function receives normalized request, options, a clone of the response, and a state object. The return value of the hook function will be used by Ky as the response object if it's an instance of [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
491
491
492
+
You can also force a retry by returning [`ky.retry(options)`](#kyretryoptions). This is useful when you need to retry based on the response body content, even if the response has a successful status code. The retry will respect the `retry.limit` option and be observable in `beforeRetry` hooks.
493
+
492
494
The `state.retryCount` is `0` for the initial request and increments with each retry. This allows you to distinguish between initial requests and retries, which is useful when you need different behavior for retries (e.g., showing a notification only on the final retry).
This allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError` with the error name `'ForceRetryError'`.
864
+
865
+
#### options
866
+
867
+
Type: `object`
868
+
869
+
##### delay
870
+
871
+
Type: `number`
872
+
873
+
Custom delay in milliseconds before retrying. If not provided, uses the default retry delay calculation based on `retry.delay` configuration.
874
+
875
+
**Note:** Custom delays bypass jitter and `backoffLimit`. This is intentional, as custom delays often come from server responses (e.g., `Retry-After` headers) and should be respected exactly as specified.
876
+
877
+
##### reason
878
+
879
+
Type: `string`
880
+
881
+
Reason for the retry. This will be included in the error message passed to `beforeRetry` hooks, allowing you to distinguish between different types of forced retries.
Exposed for `instanceof` checks. The error has a `response` property with the [`Response` object](https://developer.mozilla.org/en-US/docs/Web/API/Response), `request` property with the [`Request` object](https://developer.mozilla.org/en-US/docs/Web/API/Request), and `options` property with normalized options (either passed to `ky` when creating an instance with `ky.create()` or directly when performing the request).
Copy file name to clipboardExpand all lines: source/core/constants.ts
+79Lines changed: 79 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -62,6 +62,85 @@ export const usualFormBoundarySize = new TextEncoder().encode('------WebKitFormB
62
62
63
63
exportconststop=Symbol('stop');
64
64
65
+
/**
66
+
Options for forcing a retry via `ky.retry()`.
67
+
*/
68
+
exporttypeForceRetryOptions={
69
+
/**
70
+
Custom delay in milliseconds before retrying.
71
+
72
+
If not provided, uses the default retry delay calculation based on `retry.delay` configuration.
73
+
74
+
**Note:** Custom delays bypass jitter and `backoffLimit`. This is intentional, as custom delays often come from server responses (e.g., `Retry-After` headers) and should be respected exactly as specified.
75
+
*/
76
+
delay?: number;
77
+
78
+
/**
79
+
Reason for the retry.
80
+
81
+
This will be included in the error message passed to `beforeRetry` hooks, allowing you to distinguish between different types of forced retries.
82
+
*/
83
+
reason?: string;
84
+
};
85
+
86
+
/**
87
+
Marker returned by ky.retry() to signal a forced retry from afterResponse hooks.
88
+
*/
89
+
exportclassRetryMarker{
90
+
constructor(publicoptions?: ForceRetryOptions){}
91
+
}
92
+
93
+
/**
94
+
Force a retry from an `afterResponse` hook.
95
+
96
+
This allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.
97
+
98
+
@param options - Optional configuration for the retry.
This hook enables you to read and optionally modify the response. The hook function receives normalized request, options, a clone of the response, and a state object. The return value of the hook function will be used by Ky as the response object if it's an instance of [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
166
166
167
+
You can also force a retry by returning `ky.retry()` or `ky.retry(options)`. This is useful when you need to retry based on the response body content, even if the response has a successful status code. The retry will respect the retry limit and be observable in `beforeRetry` hooks.
168
+
167
169
@default []
168
170
169
171
@example
@@ -194,6 +196,20 @@ export type Hooks = {
194
196
}
195
197
},
196
198
199
+
// Or force retry based on response body content
200
+
async (request, options, response) => {
201
+
if (response.status === 200) {
202
+
const data = await response.clone().json();
203
+
if (data.error?.code === 'RATE_LIMIT') {
204
+
// Force retry with custom delay from API response
205
+
return ky.retry({
206
+
delay: data.error.retryAfter * 1000,
207
+
reason: 'RATE_LIMIT'
208
+
});
209
+
}
210
+
}
211
+
},
212
+
197
213
// Or show a notification only on the last retry for 5xx errors
198
214
(request, options, response, {retryCount}) => {
199
215
if (response.status >= 500 && response.status <= 599) {
0 commit comments