public void ReportErrorForScope(SequencedEvent @event, Action scope, Action<Guid?> aggregateId) { try { scope(); } catch (EndOfEventStreamException) { Thread.Sleep(200); Logger.Info("End of stream...."); } catch (TargetInvocationException e) { var unrolledException = e.UnrollDynamicallyInvokedException(); try { if (SqlTransientExceptionDetector.IsTransient(unrolledException.SourceException)) { AwaitInfrastructure(); return; } _transactor.ApplyTransactionForLambda(() => HandleError(@event, unrolledException.SourceException, aggregateId)); } catch { Logger.Error("Unable to write exception to Database"); } } catch (Exception e) { try { if (SqlTransientExceptionDetector.IsTransient(e)) { AwaitInfrastructure(); return; } _transactor.ApplyTransactionForLambda(() => HandleError(@event, e, aggregateId)); } catch { Logger.Error("Unable to write exception to Database"); } } }
private bool IsBadSequencedEvent(SequencedEvent sequencedEvent) { if (!LastBadAggregateId.HasValue) return false; if (sequencedEvent == null) return false; return LastBadAggregateId.Value == sequencedEvent.AggregateId; }
private static bool FinishedReplayingEvents(bool exitAtEndOfStream, SequencedEvent sequencedEvent) { return exitAtEndOfStream && sequencedEvent != null && !sequencedEvent.HasEvent(); }
private void PushEventImmediatelyToErrorQueue(SequencedEvent sequencedEvent) { _errorQueueLoader.PushBack(sequencedEvent.Sequence); }
private void ProcessEvent(bool exitAtEndOfStream, SequencedEvent sequencedEvent, bool includeImmediate) { if (FinishedReplayingEvents(exitAtEndOfStream, sequencedEvent)) Terminate(); Process(sequencedEvent, includeImmediate); }
private void Process(SequencedEvent sequencedEvent, bool includeImmediate) { if (sequencedEvent.AggregateId != LastBadAggregateId) _errorReporter.ReportErrorForScope(sequencedEvent, () => _handlerExecutor.HandleSequencedEvent(sequencedEvent, includeImmediate? (bool?)null: false), UpdateLastFailedAggregateId); else _errorReporter.ReportErrorForScope(() => _errorQueueLoader.PushBack(sequencedEvent.Sequence)); }
private void TransferOthersInSequence(SequencedEvent @event) { _errorQueueLoader.SeedFromIncluding(@event.Sequence, @event.AggregateId); }
private void RecordException(SequencedEvent @event, Exception e) { var error = new EventHandlerError(@event.EventType, @event.Sequence, e); if (LastError != null && LastError == error) { LastError.Increment(); _errorRepository.UpdateError(LastError); Logger.Error(String.Format("Error on event {0} {1} (count : {2})", @event.EventType, @event.Sequence, LastError.Count)); } else { _errorRepository.AddError(error); LastError = error; Logger.Error(String.Format("Error on event {0} {1} {2}", @event.EventType, @event.Sequence, e)); } }
private void HandleError(SequencedEvent @event, Exception e, Action<Guid?> aggregateId) { AddAuditRecord(@event, e); RecordException(@event, e); TransferOthersInSequence(@event); Logger.Error(String.Format("Error on event {0} {1} {2}", @event.EventType, @event.Sequence, e)); CallbackDispatcherOnAggregateIdFailure(@event, aggregateId); }
private void AddAuditRecord(SequencedEvent @event, Exception e) { _auditRepository.Add(new EventHandlerAudit(@event.Event, DateTime.UtcNow, EventHandlerAuditResult.Failed, e.Message)); }
private static void CallbackDispatcherOnAggregateIdFailure(SequencedEvent @event, Action<Guid?> aggregateId) { aggregateId(@event.AggregateId); }