RunEither
Package Trax.CoreNamespace Trax.Core.TrainSource Train.cs
Executes the train from outside it and returns the result as an Either<Exception, TReturn>: Right on success, Left holding the exception on failure. Run throws instead.
Signature
// Train<TInput, TReturn>, inherited unchanged by ServiceTrain<TIn, TOut>
public Task<Either<Exception, TReturn>> RunEither(TInput input);Parameters
| Parameter | Type | Description |
|---|---|---|
input | TInput | The train's input |
Returns
Task<Either<Exception, TReturn>>. Nothing escapes it: a junction's exception, an exception Junctions() throws, and a cancelled run (as OperationCanceledException) all come back as Left. See Either and Unit.
Behavior
- Seeds Memory with the input and runs
Junctions(), asRundoes, without unwrapping the result. - Takes no
CancellationToken. It runs with the train's currentCancellationToken, which a caller cannot set; pass a token toRun, or run the train through a host (the mediator or the scheduler), which sets it. - On a
ServiceTrainit runs the chain only: no metadata row is created, no lifecycle hook fires and no outcome is written, and anEffectJunctionin the chain fails with aTrainExceptionbecause the run has no metadata.Rundoes those. - A cancelled run's
Leftis anOperationCanceledException; test for it before treating theLeftas a business failure.
Example
using Trax.Core.Functional;
using Trax.Core.Train;
public class OrderPreview
{
public async Task<string> Process(OrderInput input)
{
var result = await new LocalOrderTrain().RunEither(input);
return result.Match(
Right: success => $"Order processed: {success.ConfirmationId}",
Left: error => error is OperationCanceledException ? "Cancelled" : $"Failed: {error.Message}"
);
}
}
public class LocalOrderTrain : Train<OrderInput, OrderResult>
{
protected override Task<Either<Exception, OrderResult>> Junctions() =>
Extract<OrderInput, OrderDetails>().Chain<ProcessOrder>().Resolve();
}