Skip to content

Return a result or an error

Goal: your command needs to return more than a single event — maybe a generated id the caller needs, maybe a typed failure, maybe several events at once.

A command’s Handle() method returns the event(s) it produced, and Arc appends them. The shape you return is how you express intent — Arc understands several, so pick the one that fits rather than bending your logic to a single form.

Return the shape that matches the outcome:

You want to…Return
record one event (source from the command’s [Key])the event: AuthorRegistered Handle()
record one event against an explicit sourcea tuple: (AuthorId, AuthorRegistered) Handle()
also hand the caller a valuea tuple of (result, event)
reject with a typed failure or succeedResult<ValidationResult, AuthorRegistered>
record several eventsreturn them together as an IEnumerable<…>
record nothingvoid

The Result<,> form is how a handler rejects based on state it had to consult — return ValidationResult.Error("…") to fail, or the event to proceed:

public Result<ValidationResult, AuthorRegistered> Handle(RegisteredAuthorName? existing) =>
existing is not null && existing.Name != AuthorName.NotSet
? ValidationResult.Error("An author with that name is already registered.")
: new AuthorRegistered(Name);

Whatever the handler returns, the generated proxy gives the caller a CommandResult. Check isSuccess, read any returned value off the result, and inspect validation errors when it failed — the same object carries all three.