Comments (5)
@elbywan Thanks for that. It works indeed!
from wretch.
Hi @dalwlad !
You can indeed do that using a middleware, but if you need to retry a request on 401/403 (or any other error) you can also use catchers which should be easier.
I wrote an example of doing this in the following issue or in the docs.
And if you still need to use middlewares for this, I can post a code sample later today or tomorrow !
from wretch.
Thanks for the quick reply @elbywan. I've seen the example for how to use the catchers for this and they work just fine. But if you would need to implement the retry mechanism for any call that is hitting the api, that would become tedious. The use case I'm working right now has a requirement like : for all outgoing requests, there should be a retry mechanism, ideally indefinite, but the delay should be detemined by some sort of exponential function, with capping values: for example start at 100ms and increase it, but no more than 1000ms. In other words, you receive an error for a request, wait 100ms and try again, Next time, if you still receive the error, increase the timeout and try again ... you got the idea.
I was trying something like below, but got stuck on the resolve part where for the second attempt, it fails because the wretch call doesn't have any rejection handling.
const DEFAULTS = {
ERROR_CODES : []
};
const reconnectMiddleware = ({
errorCodes = DEFAULTS.ERROR_CODES
} = {}) => {
const tracker = new Map();
errorCodes.map(code => {
tracker.set(code, new Map());
});
return next => (url, options) => {
const req = next(url, options);
req.then(response => {
if (tracker.has(response.status)) {
if (!response.ok) {
const requestKey = `${options.method}@${url}`;
const numberOfAttemptsMade = tracker.get(response.status).get(requestKey) || 0;
tracker.get(response.status).set(requestKey, numberOfAttemptsMade + 1);
return new Promise(resolve => {
const delay = Math.max(DEFAULTS.DELAY * numberOfAttemptsMade, 1000);
setTimeout(() => {
resolve(wretch(url)[options.method.toLowerCase()](options));
}, delay);
});
}
tracker.set(response.status, new Map());
}
return response;
});
req.catch(response => {
const requestKey = `${options.method}@${url}`;
const numberOfAttemptsMade = tracker.get(response.status).get(requestKey) || 0;
tracker.get(response.status).set(requestKey, numberOfAttemptsMade + 1);
return new Promise(resolve => {
const delay = Math.max(DEFAULTS.DELAY * numberOfAttemptsMade, 1000);
setTimeout(() => {
resolve(wretch(url)[options.method.toLowerCase()](options));
}, delay);
});
});
return req;
};
};
export default reconnectMiddleware;
from wretch.
@dalwlad Just made some corrections to your snippet, can you check with the code below ? I'm pretty sure it should work 😉 .
const DEFAULTS = {
DELAY: 100,
MAX_ATTEMPTS: 10,
ERROR_CODES : []
};
const reconnectMiddleware = ({
errorCodes = DEFAULTS.ERROR_CODES
} = {}) => {
const tracker = new Map();
errorCodes.map(code => {
tracker.set(code, new Map());
});
return next => (url, options) => {
const checkStatus = (response) => {
if (tracker.has(response.status)) {
if (!response.ok) {
const requestKey = `${options.method}@${url}`;
const numberOfAttemptsMade = tracker.get(response.status).get(requestKey) || 0;
tracker.get(response.status).set(requestKey, numberOfAttemptsMade + 1);
// Maybe add a maximum number of attempts ?
if(numberOfAttemptsMade >= MAX_ATTEMPTS)
return response
// We need to recurse until we have a correct response and chain the checks
return new Promise(resolve => {
const delay = Math.min(DEFAULTS.DELAY * numberOfAttemptsMade, 1000);
setTimeout(() => {
resolve(next(url, options));
}, delay);
}).then(checkStatus);
}
// If ok - reset the map and return the response
tracker.set(response.status, new Map());
return Promise.resolve(response);
}
return response
}
// Willingly omitted .catch which prevents handling network errors and should throw
return next(url, options).then(checkStatus);
};
};
from wretch.
Great ! Closing the issue then !
from wretch.
Related Issues (20)
- Where is the full documentation? HOT 2
- Support for universal error catcher HOT 3
- CatherFallback type error HOT 3
- Using PerfsAddon HOT 2
- More resilient handling of `/` when concatenating urls HOT 6
- Timeout and catch it HOT 3
- Upload file with file;filename (multiple parameters) HOT 2
- How should 304 responses be handled? HOT 2
- Addon for upload progress HOT 5
- Error: Package subpath './middlewares' is not defined by "exports"
- Wrong condition in FormDataAddon and not converting FileList to `file[]` format HOT 1
- I get an error when I try to get an ArrayBuffer HOT 6
- Will this API work with the React 18 and/or NextJS extension to the fetch API? HOT 2
- Headers merging issue when using fetch headers object HOT 2
- Modify request and response HOT 4
- fetchError not being called HOT 2
- onAbort on instance HOT 2
- .then() is also called on caught errors HOT 2
- Cannot read properties of undefined (reading 'wretch') HOT 2
- 2.7.1 is causing a terser issue in my applications HOT 6
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 wretch.