run method
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;
}
}