vercel/async-retry

Add option to decide if retry should be attempted?

salmanm opened this issue · 3 comments

I know there's feature to bail out conditionally, but I think it would be useful to have a function that is called as soon as the operation fails, and the return value of that function should decide whether or not the next retry should happen.

So if (!op.retry(err)) { would just become something like if (!options.shouldRetry(err) || !op.retry(err)) {.

Current alternative to this would be to have a try/catch in the retrier function, decide in catch, throw if need to retry, and swallow and bail if needed. But this is a lot of boilerplate and can not be extracted into a separate function.

While having a function in option would be much easier.

Did it make sense?

Hey

I am trying to do same as you, can you please provide the sample code to get it to work

thanks

That's not so much boilerplate you can bail return in a catch if it matches your condition otherwise rethrow. Here's an example from an intercom api call:

await retry(async bail => {
      try {
        const res = await client.users.create(intercomUser)

        if ([400, 401, 409, 500].indexOf(res.statusCode) !== -1) {
          // don't retry
          bail(new Error(`Could not retry: status code ${res.statusCode}`))
        }
      } catch (error) {
        // fail silently don't bail
        if (/Multiple existing/.test(error.message)) {
          return
        }
        throw (error)
      }
    })

EDIT: do not bail in the catch, somehow it throws unhandeld

Not being able to "bail" in the catch is a huge limitation. Most of the time you would want to bail based on an thrown error condition...