retry failed request in the onResponse middleware #2089
Replies: 5 comments 1 reply
-
I thought of an ability to call the coreFetch function with fetchOptions passed to the original request. export const middleware: Middleware = {
async onResponse({ response, request, originalFetchOptions, schemaPath }) {
client.coreFetch(schemaPath, initialFeatchOptions)
}
} or export const middleware: Middleware = {
async onResponse({ response, request }) {
client.coreFetch(request)
}
} Both imply that the coreFetch function would have to be returned from the createClient initializer and the latter implies that the coreFetch would handle the first parameter by branching using the following condition if (schemaPath instanceof Request) {
...
} else {
...
} |
Beta Was this translation helpful? Give feedback.
-
Let me know if it makes any sense at all. Or, perhaps, there are easier ways to achieve this w/o making changes to the source code. Thanks! |
Beta Was this translation helpful? Give feedback.
-
I've got one more idea and it's to use native fetch just like this. Are there any potential problems with this I need to be aware of? import { authService, TLoginResponse } from '@/shared/auth'
import { Middleware } from 'openapi-fetch'
let refreshPromise: Promise<TLoginResponse | undefined> | null = null
export const middleware: Middleware = {
async onResponse({ response, request }) {
if (response.ok) return response
else {
if (response.status === 401) {
try {
// ...
if (refreshResponse) {
// ...
try {
return fetch(request)
} catch (innerError) {
if (innerError.status === 401) {
throw innerError
}
}
}
} catch (error) {
// ...
} finally {
refreshPromise = null
}
}
}
},
} |
Beta Was this translation helpful? Give feedback.
-
would really love retry mechanism |
Beta Was this translation helpful? Give feedback.
-
@sahandsn Here's the solution I'm using and it's working fine for me. The platformClient.use({
async onResponse({ request, response }) {
const { ok, status } = response;
if (!ok) {
if (status === 401) {
const url = new URL(request.url);
if (ignoreUnauthorized.includes(url.pathname)) {
return response;
}
// console.log("onResponse", url.pathname, response.status);
const refresh = await platformClient
.POST("/auth/refresh")
.then((r) => r.response.ok)
.catch((_err) => false);
if (!refresh) {
// Failure to refresh.
onAuthFailure();
return response;
}
const retry = await fetch(new Request(request));
if (retry.ok) {
return retry;
}
if (retry.status === 401) {
// Failure: The retry is also a 401. This should not happen.
onAuthFailure();
return retry;
}
// Else, throw HttpResponseError (below).
response = retry;
}
const url = new URL(request.url);
throw new HttpResponseError(
`HTTP[${response.status}](${request.method}:${url.pathname}): ` +
response.statusText,
response,
);
}
return response;
},
}); NOTE: I treat all non-2xx responses exceptionally, as exceptions, in my app. Easy to remove. Also, I don't mind that my retry is not being processed by any EDIT: Also, in |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello there! I've been trying to implement the refresh session functionality for quite some time using the response middleware.
The stumbling block is to retry the failed request inside the middleware. In the following code snippet, I am registering the Middleware and in the onResponse handler I'd like to add the retry line of the original request (look for the comment '// retry request here').
Any consultation would be greatly appreciated.
Beta Was this translation helpful? Give feedback.
All reactions