Skip to content

feat: add retry util#157

Open
FarajiOranj wants to merge 1 commit into
ryangoree:mainfrom
FarajiOranj:feat/retry-util
Open

feat: add retry util#157
FarajiOranj wants to merge 1 commit into
ryangoree:mainfrom
FarajiOranj:feat/retry-util

Conversation

@FarajiOranj

Copy link
Copy Markdown

Summary

Closes #136.

Adds a built-in retry utility that calls a function and retries it if it
throws, until it succeeds or a maximum number of attempts is reached. The docs
showed a couple of hand-rolled retry loops; this makes it a first-class helper.

Usage

import { retry } from "@gud/drift";

const hash = await retry(() => drift.write({ abi, address, fn, args }), {
  maxAttempts: 5,
  // Only retry transient errors.
  shouldRetry: (error) => isTransient(error),
});

API

retry(action, options?) calls action(attempt) (1-based) and returns its
result, retrying on throw. Options:

  • maxAttempts (default 3) - total attempts, including the first. Values
    less than 1 are treated as 1 (the action always runs at least once).
  • delay - the wait before each retry in ms, or a function of the failed
    attempt number. Defaults to an exponential backoff (100ms, 200ms, ...).
  • shouldRetry (error, attempt) => boolean | Promise<boolean> - return
    false to rethrow immediately. Defaults to always retrying until
    maxAttempts.

On the final attempt it throws the last error without waiting or consulting
shouldRetry, and a throwing delay strategy never masks the action's error.

Also exports RetryOptions, DEFAULT_MAX_ATTEMPTS, and defaultRetryDelay, and
updates the "Retry Logic" docs to point at the built-in util.

Notes / possible follow-up

The issue also mentions "possibly options on client operations for automatic
retries." I kept this PR to the standalone utility (which composes with any
operation); wiring per-operation retry options into the client would make a good
follow-up.

Tests

retry.test.ts covers success without retry, retry-until-success, throwing the
last error, maxAttempts (incl. <= 1), attempt numbering, the delay strategy,
shouldRetry (false / awaited / not-called-on-final), and that a throwing delay
strategy rethrows the original error.

Add a `retry` utility that calls a function and retries it if it throws, until
it succeeds or a maximum number of attempts is reached. Configurable via
`maxAttempts`, `delay` (a fixed ms value or a function of the attempt number,
defaulting to an exponential backoff), and a `shouldRetry` predicate. The action
always runs at least once, and a throwing delay strategy can't mask the action's
error.
@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d3a1d98

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@gud/drift Minor
@gud/drift-ethers-v5 Minor
@gud/drift-ethers Minor
@gud/drift-viem Minor
@gud/drift-web3 Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a retry util

1 participant