/// <inheritdoc /> /// <summary> /// Wrap the handler and redirect all exception to <see cref="IErrorLog"/> /// </summary> public async Task Handle(T command) { _log.Trace($"{command.GetType().Name}", this); var timeline = _timeline.Id; if (!(command is IRetroactiveCommand) && command.Timestamp == default) { command.Timestamp = _timeline.Now; } if (command.LocalId == default) { command.LocalId = new EventId(Configuration.ReplicaName, command.Timestamp); } if (command.OriginId == default) { command.OriginId = new EventId(Configuration.ReplicaName, command.Timestamp); } command.Timeline = timeline; try { await _handler.Handle(command); if (command.StoreInLog && !command.Pure) { await _commandLog.AppendCommand(command); } } catch (Exception e) { _errorLog.Add(e); // check that we didn't end up on wrong timeline if (_timeline.Id != timeline) { var tException = new InvalidOperationException($"Execution started on {timeline} but ended on {_timeline.Id}"); _errorLog.Add(tException); // throw tException; await _branchManager.Branch(timeline); } await _commandLog.AddFailedCommand(command); } }