Skip to content

waitForFillByDepositTx: infinite polling loop with no termination condition, errors swallowed #271

Description

@Nexory

Summary

waitForFillByDepositTx in packages/sdk/src/actions/getFillByDepositTx.ts wraps a polling loop in a Promise that only has a resolve path. It can never reject, has no maximum-attempt count, no timeout, and no cancellation support. Every error (including NoFillLogError, thrown when the fill does not yet exist) is caught, logged, and immediately rescheduled, so a caller waiting for a deposit that is never filled polls forever and leaks the event loop.

Location (current HEAD)

packages/sdk/src/actions/getFillByDepositTx.ts (around lines 138-154):

return new Promise((res) => {        // no `rej` parameter
  const poll = () => {
    getFillByDepositTx(params)
      .then((response) => {
        if (response.fillTxReceipt) {
          res(response);
        } else {
          setTimeout(poll, interval);  // retry forever on "not yet filled"
        }
      })
      .catch((error) => {
        params?.logger ? params.logger.error(error) : console.log(error);
        setTimeout(poll, interval);    // retry forever on ANY error
      });
  };
  poll();
});

Three combined problems

  1. No reject handle: the returned Promise can never settle with an error.
  2. Errors swallowed unconditionally: NoFillLogError, RPC failures, network timeouts, and logic errors all just reschedule.
  3. No max-attempts / timeout / cancellation: an unfilled deposit polls indefinitely and leaks the process/event loop.

Suggested fix

Add a reject path, a configurable maxAttempts (or overall timeout), and optional AbortSignal cancellation; surface a terminal error (after N attempts or on non-retryable errors such as NoFillLogError) instead of swallowing everything.

(Originally reported in across-protocol/relayer#3434; re-filing here since the affected code lives in this repository.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions