loadable-components: Implement retry in case of error
🚀 Feature Proposal
Implement a new “retry” option in @loadable/component.
Motivation
We monitor our errors with Sentry and we see quite a lot of errors coming with lazy-loaded components. Indeed, on flaky network, it’s easy to have a request aborted and the component is never loaded. In our applications, we have started to wrap all dynamic imports passed to loadable with a retry function such as:
const Example = loadable(() =>
retry(
() => import('./Example'),
{ retries: 3 }
)
)
where retry is a simple function:
type Options = {
retries?: number
interval?: number
exponentialBackoff?: boolean
}
// taken from https://dev.to/goenning/how-to-retry-when-react-lazy-fails-mb5
export function retry<R>(
fn: () => Promise<R>,
{ retries = 3, interval = 500, exponentialBackoff = true }: Options = {}
) {
return new Promise<R>((resolve, reject) => {
fn()
.then(resolve)
.catch((error) => {
setTimeout(() => {
if (retries === 1) {
reject(error)
return
}
// Passing on "reject" is the important part
retry(fn, {
retries: retries - 1,
interval: exponentialBackoff ? interval * 2 : interval,
}).then(resolve, reject)
}, interval)
})
})
}
Example
const Example = loadable(() => import('./Example'), {retries: 3})
Pitch
I’m wondering if this is something that could be directly implemented as part of loadable.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 22
- Comments: 33 (1 by maintainers)
Good point. As a matter of fact - our own Sentry is filled with the same reports.
I think this issue is still relevant. My last question was not answered actually.
This issue is still relevant.
Not stale
@YPCrumble you need to use a generic signature. I have updated my original message with what you are looking for 😉
This issue is still problematic, if it’s not prioritized / fixable at the moment can we link this in the docs? Discoverability of this solution can help future users from wasting few hours hopefully.
Loadable babel plugin is reading your imports and create another structure which is expected to “do the same”. But logic there is very simply - it reads a file from the import and rewrites it to
requirefor SSR. In other words - all your “additions” will be just discarded.See test - https://github.com/gregberge/loadable-components/blob/main/packages/babel-plugin/src/__snapshots__/index.test.js.snap#L27-L56
Funny how I also did the exact same thing with retry and it works. I’m not sure if it should really be incorporated in this library though, its easier to maintain one simple library than a do-all giant. An entry in the docs would suffice, if you ask me. Another entry I’d expect (which is what I was looking for, and stumbled upon this issue instead) is to generally describe some good practices on what to do in case of fail, so how to “wrap” things with try catch and what are our options to safely recover from this (because even retrying network requests will return with error eventually, unless you want to repeat it indefinitely)
@ValentinH worked perfectly, thank you @ValentinH !!!
It’s more about the general unpredictibility of the result. Let’s double-check if #511 can solve your issue. Probably with the minimal changes we can teach
guardtoretryimport if needed. cc @hedgepigdanielHello! Facing the same issue from some time. I would like to try @ValentinH solution, will let you know when it will be tested it on production in my project