Skip to content

[feat] Add onRetry and onCircuitStateChange lifecycle hooks #35

Description

@AryanSharma48

Problem

SmoothAPI provides retry and circuit breaker functionality, but there is currently no way for users to observe these lifecycle events.

Applications may want to use these events for:

  • Logging retry attempts
  • Collecting metrics
  • Monitoring circuit breaker state
  • Debugging API failures
  • Integrating SmoothAPI with observability systems

The project roadmap identifies event hooks as a potential feature.

Proposed Solution

Add two optional lifecycle callbacks to the TypeScript configuration:

onRetry?: (attempt: number, error: unknown) => void

onCircuitStateChange?: (
  domain: string,
  state: 'OPEN' | 'CLOSED' | 'HALF_OPEN'
) => void

onRetry

The onRetry callback should be called whenever SmoothAPI is about to perform a retry.

It should receive:

  • attempt: The retry attempt number
  • error: The error that caused the retry

Example:

const fetch = createSmoothFetch({
  onRetry: (attempt, error) => {
    console.log(`Retry attempt ${attempt}`, error);
  }
});

onCircuitStateChange

The onCircuitStateChange callback should be called whenever the circuit breaker transitions between states.

It should receive:

  • domain: The circuit/domain associated with the transition
  • state: The new circuit state

Example:

const fetch = createSmoothFetch({
  onCircuitStateChange: (domain, state) => {
    console.log(`${domain} circuit changed to ${state}`);
  }
});

Implementation

The implementation should:

  1. Add the optional callbacks to the appropriate TypeScript configuration types.
  2. Invoke onRetry at the appropriate point in the retry flow.
  3. Invoke onCircuitStateChange whenever the circuit breaker transitions between states.
  4. Add unit tests covering both callbacks.
  5. Ensure callback errors do not break SmoothAPI's retry or circuit breaker behavior.

Acceptance Criteria

  • onRetry is available in the SmoothAPI configuration.
  • onCircuitStateChange is available in the SmoothAPI configuration.
  • onRetry is called before a retry is performed.
  • onRetry receives the correct attempt number and error.
  • onCircuitStateChange fires when the circuit state changes.
  • The callback receives the correct domain and new state.
  • Unit tests cover both callbacks.
  • Existing SmoothAPI behavior remains unchanged when the callbacks are not provided.
  • Errors thrown inside callbacks do not break the retry or circuit breaker flow.
  • The TypeScript project builds successfully.
  • The existing test suite continues to pass.

Files to Look At

  • packages/smooth-api-ts/src/types.ts
  • packages/smooth-api-ts/src/index.ts
  • packages/smooth-api-ts/src/state.ts
  • Existing TypeScript tests under packages/smooth-api-ts/tests/

Prerequisites

  • Strong TypeScript knowledge
  • Familiarity with callbacks
  • Basic understanding of state machines
  • Basic unit testing knowledge

Notes

This is intentionally a stretch issue and is not expected to be suitable for first-time contributors.

Before implementing the feature, please familiarize yourself with the existing retry flow and circuit breaker state transitions.

Please avoid unrelated refactoring or architectural changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    advancedAdvance knowledge of codebase neededenhancementNew feature or requeststretchMore challenging issuestypescript

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions