Skip to content

[copilot-finds] Test: RetryableTask missing coverage for non-retriable failures, remaining-timeout guard, and complete() override #219

@github-actions

Description

@github-actions

Problem

RetryableTask.computeNextDelayInMilliseconds() has three untested code paths that guard against critical failure modes:

  1. Non-retriable failure guard (line 63-65): Returns undefined when lastFailure.isNonRetriable is true, preventing retries of fundamentally broken operations (e.g., activity not found, version mismatch). No test covers this path.

  2. Delay-exceeds-remaining-timeout guard (lines 106-113): Returns undefined when the computed retry delay would exceed the remaining timeout window. The existing timeout test only verifies that elapsed time exceeding the timeout stops retries, but not that a computed delay overshooting the remaining time stops retries. These are two distinct code paths in the method (lines 86-91 vs lines 106-113).

  3. complete() override from RetryTaskBase (line 129-136): Clears _exception and _lastFailure when a retry succeeds. While RetryHandlerTask tests this behavior, RetryableTask (the more commonly used policy-based retry) does not, despite being a separate subclass.

File references:

  • packages/durabletask-js/src/task/retryable-task.ts lines 61-116
  • packages/durabletask-js/src/task/retry-task-base.ts lines 129-136
  • packages/durabletask-js/test/retryable-task.spec.ts (existing tests)

Root Cause

The existing test suite covers standard retry scenarios (backoff, max attempts, elapsed timeout, handleFailure predicate) but omits these edge-case guards that protect against:

  • Infinite retry loops for non-retriable failures
  • Scheduling timers past the timeout window
  • Stale failure state leaking across retry success

Proposed Fix

Add three new test cases to retryable-task.spec.ts covering each untested path.

Impact

Severity: Medium — Without test coverage, a regression removing the non-retriable guard would cause infinite retry loops for "activity not found" errors. The remaining-timeout guard prevents scheduling pointless timers.

Confidence: High — These are concrete, verifiable code paths with zero test coverage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    copilot-findsFindings from daily automated code review agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions