run method

Future<Final> run(
  1. Initial initialData, {
  2. StepListener? listener,
})

Runs the chain with given initial data

Returns the final transformed data Throws if any step fails and rollback is unsuccessful

Implementation

Future<Final> run(
  Initial initialData, {
  StepListener? listener,
}) async {
  dynamic currentData = initialData;
  final completedSteps = <StepState<dynamic, dynamic>>[];

  try {
    for (final step in _steps) {
      if (context.shouldAbort) {
        await _rollback(completedSteps, listener);
        throw ChainAbortedException();
      }

      final state = StepState<dynamic, dynamic>(
        step: step,
        input: currentData,
        status: StepStatus.inProgress,
        startTime: DateTime.now(),
      );
      _history.add(state);
      listener?.onStepChanged(state);

      try {
        final output = await step.handle(currentData, context);
        final completedState = state.copyWith(
          output: output,
          status: StepStatus.completed,
          endTime: DateTime.now(),
        );
        _updateState(completedState);
        listener?.onStepChanged(completedState);
        completedSteps.add(completedState);
        currentData = output;
      } catch (error) {
        final errorState = state.copyWith(
          status: StepStatus.error,
          endTime: DateTime.now(),
          error: error,
        );
        _updateState(errorState);
        listener?.onStepChanged(errorState);
        rethrow;
      }
    }

    if (currentData is! Final) {
      throw StateError(
        'Chain output type mismatch: expected $Final but got ${currentData.runtimeType}',
      );
    }
    return currentData;
  } catch (e) {
    if (shouldRollbackOnError && e is! ChainAbortedException) {
      try {
        await _rollback(completedSteps, listener);
      } catch (rollbackError) {
        throw ChainRollbackException(e, rollbackError);
      }
    }
    rethrow;
  }
}