Comments (3)
It was not easy but we managed to come up with a solution so that 401 errors can be captured correctly. The solution supports simultaneous calls, which are saved until the token is refreshed.
What cannot be done from the library is to call back in the response interceptor the failed requests that have config, so it was solved by saving all the configs of the requests (don't worry, they are then deleted in the removeDataRequestsItem
method) in an object in the request interceptor, to be able to be accessed in the response interceptor. A great addition to the library (which would save us having to do this step) would be to be able to access the initial config of the requests from the response interceptor.
This is the code (just use your refresh
service, your REFRESH_URL
and your logout
method):
import fetchIntercept from 'fetch-intercept';
import { refresh, REFRESH_URL } from '...';
interface IDataRequest {
[key: string]: Request;
}
export const CreateInterceptors = (() => {
let instance;
const init = () => {
let isRefreshing = false;
let refreshSubscribers = [];
let dataRequests = {} as IDataRequest;
const logoutUser = () => {
console.log("logout method here");
};
const subscribeTokenRefresh = callback => {
refreshSubscribers.push(callback);
};
const onRefreshed = () => {
refreshSubscribers.map(callback => callback());
refreshSubscribers = [];
};
const removeDataRequestsItem = requestKey => {
const { [requestKey]: _omit, ...remaining } = dataRequests;
dataRequests = remaining;
};
const getRelativeUrl = url => url.replace(window.location.origin, '');
return {
registerInterceptors: () => {
fetchIntercept.register({
request(url, config) {
if (config && url.indexOf(REFRESH_URL) === -1) {
dataRequests = {
...dataRequests,
[`${getRelativeUrl(url)}_${config.method || 'GET'}`]: config,
};
}
return [url, config];
},
response(response) {
const requestKey = `${getRelativeUrl(response.url)}_${response.request.method}`;
if (response.status === 401 && response.url.indexOf(REFRESH_URL) === -1) {
if (!isRefreshing) {
isRefreshing = true;
refresh()
.then(() => {
isRefreshing = false;
onRefreshed();
})
.catch(() => logoutUser());
}
const retryOrigReq: any = new Promise((resolve, reject) => {
subscribeTokenRefresh(() => {
fetch(response.url, {
...dataRequests[requestKey],
})
.then(origReqResponse => {
resolve(origReqResponse);
removeDataRequestsItem(requestKey);
})
.catch(err => {
reject(err);
});
});
});
return retryOrigReq;
}
removeDataRequestsItem(requestKey);
return response;
},
});
},
};
};
return {
getInstance() {
if (!instance) {
instance = init();
}
return instance;
},
};
})();
Then import it and call registerInterceptors
:
import { CreateInterceptors } from '...';
const interceptors = CreateInterceptors.getInstance();
interceptors.registerInterceptors();
from fetch-intercept.
@gaspartripodiglobant Thanks mate
from fetch-intercept.
I solved this by applying a patch-package to fetch-intercept
so that it will save the request
(which already does) and the rawRequest
(created by me - it will store the arguments [url, config]
passed on the request intereceptor) on the response.rawRequest
and error.rawRequest
.
This way I always have access to the original config and original url.
from fetch-intercept.
Related Issues (20)
- Best way to unit test an interceptor? HOT 1
- Is this still maintained? HOT 3
- Handling refresh token by recall same request after refreshing the token HOT 7
- fetch-intercept in React HOT 1
- Re-use interceptor across multiple files HOT 2
- typing file incorrect HOT 1
- No fetch avaibale. Unable to register fetch-intercept HOT 1
- Don't work together with fetch-mock HOT 1
- How to transform the data?
- Intercepting 401 or responses not working? HOT 1
- Include fetch request inside Response and ResponseError HOT 4
- Headers are not able to add HOT 4
- How to implement refresh token? HOT 4
- Possible to use this lib w/ isomorphic-fetch instead of whatwg-fetch? HOT 3
- How to pass in an arbitrary object as state from request to response or error? HOT 3
- TS Type mismatch when response is async function or returns promise HOT 2
- Cannot read property 'fetch' of undefined when running tests in create-react-app HOT 1
- triger cors when work with swr
- How can I read `response.request.body` in `response`? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fetch-intercept.