Repository navigation
Replies: 1 comment
|
The POST body is normally already consumed by the time function with401Retry(
refreshAccessToken: () => Promise<string>,
fetchOnce: (request: Request) => Promise<Response> = globalThis.fetch,
): (request: Request) => Promise<Response> {
return async (request) => {
const replay = request.clone();
try {
const response = await fetchOnce(request);
if (response.status !== 401) return response;
// This response is being replaced; release its unread body.
if (response.body && !response.body.locked) {
void response.body.cancel().catch(() => {});
}
const token = await refreshAccessToken();
replay.headers.set('Authorization', `Bearer ${token}`);
// Use the underlying transport, not this wrapper: retry only once.
return await fetchOnce(replay);
} finally {
if (replay.body && !replay.bodyUsed && !replay.body.locked) {
// Don't wait for the other branch of the tee to finish.
void replay.body.cancel().catch(() => {});
}
}
};
}
const client = createClient<paths>({
baseUrl: 'https://api.example.com',
fetch: with401Retry(refreshAccessToken),
});This uses your existing Keep the refresh call outside this same retrying client, and coalesce concurrent refreshes if your token flow needs that. Only replay requests your API permits you to retry safely. This pattern is for bounded JSON bodies: cloning tees the stream and can buffer it, so large or streaming uploads need a separate replay strategy. Tested on See the docs on body statefulness and the custom fetch option. |
Uh oh!
There was an error while loading. Please reload this page.
I'm trying to create a middleware that retries a request when it returns a 401 status code. I've already created a functional version that refreshes tokens and can retry GET requests. However, I'm unable to access the POST request body within the
onResponsefunction. My goal is to update a header and retry the request. Is there a built-in way to achieve this? 🤔All reactions