public override void OnException(HttpActionExecutedContext context) { Exception exp; try { var logLevel = GetLogLevel(context.Exception); _logException(context.Exception, logLevel); var error = ToError(context.Exception); var httpResponseMessage = new HttpResponseMessage { StatusCode = GetStatusCode(context.Exception), ReasonPhrase = context.Exception.Message, RequestMessage = context.Request, Content = new ObjectContent<Error>(error, new JsonMediaTypeFormatter(), "application/json"), }; exp = new HttpResponseException(httpResponseMessage); } catch (Exception exception) { var e = new AggregateException(exception, context.Exception); _logException(e, LogLevel.SystemError); throw; } throw exp; }
public void Should_flatten_aggregate_exceptions() { var exception1 = new Exception("Exception 1", new Exception("Inner exception of exception 1")); var exception2 = new Exception("Exception 2", new Exception("Inner exception of exception 2")); var exception3 = new Exception("Exception 3", new Exception("Inner exception of exception 3")); // Aggregate exceptions nested three levels deep. var aggregate3 = new AggregateException(exception3); var aggregate2 = new AggregateException(aggregate3, exception2); var aggregate1 = new AggregateException(aggregate2, exception1); var result = aggregate1.FlattenInnerExceptions(); Assert.IsType<AggregateException>(result); // Only the inner exceptions of any aggregates should be returned. The inner exception // of a non-aggregate should not be flattened. var innerExceptions = ((AggregateException)result).InnerExceptions; var expectedExceptions = new[] { exception1, exception2, exception3 }; Assert.Equal(3, innerExceptions.Count); foreach (var exception in expectedExceptions) Assert.True(innerExceptions.Contains(exception)); }
static void DumpException(StringBuilder sb, int indent, AggregateException aggregateException) { AppendWithIndent(sb, indent, aggregateException); foreach (var ex in aggregateException.InnerExceptions) DumpException(sb, indent + 1, ex); }
private void Warn () { try { numReports += 1; // Create a collection container to hold exceptions List<Exception> exceptions = new List<Exception>(); // We have an exception with an innerexception, so add it to the list exceptions.Add(new TimeoutException("This is part 1 of aggregate exception", new ArgumentException("ID missing"))); // Another exception, add to list exceptions.Add(new NotImplementedException("This is part 2 of aggregate exception")); // All done, now create the AggregateException and throw it AggregateException aggEx = new AggregateException(exceptions); throw aggEx; } catch(Exception exp) { Xamarin.Insights.Report(exp, new Dictionary <string, string> { {"warning-local-time", DateTime.Now.ToString()} }, Xamarin.Insights.Severity.Warning); MessagingCenter.Send<TrackViewModel, string>(this, "Alert", "Warning registered"); } }
public Error MapMessageToErrorSchema(AggregateException exception, string correlationId, string messageType, string payload, MessageProperties properties, IDictionary<string, object> headers, MessageReceivedInfo info) { return new Error { errorDateTime = DateTime.Now, errorType = ErrorTypeEnum.ApplicationError, component = exception.InnerException.Source, server = Environment.MachineName, serviceName = messageType, summary = exception.InnerException.Message, detail = exception.InnerException.StackTrace, original = new OriginalDetails { jobId = correlationId, exchangeName = (info == null) ? string.Empty : info.Exchange, queueName = (info == null) ? string.Empty : info.Queue, payload = payload, correlationId = correlationId, routingKey = (info == null) ? string.Empty : info.RoutingKey, deliveryMode = properties.DeliveryMode.ToString(), headers = ConvertDictionaryToHeaderDetails(headers), headerProperties = ConvertMessagePropertiesToHeaderDetails(properties) } }; }
/// <summary> /// Starts a list of tasks. /// </summary> /// <param name="tasks">The tasks to start.</param> /// <param name="exceptions">The variable where to write the occurred exceptions to.</param> /// <param name="scheduler">The custom scheduler to use.</param> /// <returns> /// The started tasks or <see langword="null" /> if <paramref name="tasks" /> is also <see langword="null" />. /// </returns> public static Task[] StartAll( this IEnumerable<Task> tasks, out AggregateException exceptions, TaskScheduler scheduler = null) { exceptions = null; if (tasks == null) { return null; } var occurredExceptions = new List<Exception>(); var startedTasks = new List<Task>(); try { using (var e = tasks.GetEnumerator()) { while (e.MoveNext()) { try { var t = e.Current; if (t == null) { continue; } if (scheduler == null) { t.Start(); } else { t.Start(scheduler); } startedTasks.Add(t); } catch (Exception ex) { occurredExceptions.Add(ex); } } } } catch (Exception ex) { occurredExceptions.Add(ex); } if (occurredExceptions.Count > 0) { exceptions = new AggregateException(occurredExceptions); } return startedTasks.ToArray(); }
private static IEnumerable<string> GetAggregateExceptionMessages(AggregateException exception) { foreach (var ie in exception.InnerExceptions) { yield return ie.Message; } }
public static void HandleException(AggregateException ex, Activity activity) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.SetTitle("One or more Error(s)"); builder.SetMessage("First:" + ex.InnerExceptions.First().Message); builder.Create().Show(); }
/// <summary> /// return true for socket errors, and RedisTimeoutException /// </summary> /// <param name="callError"></param> /// <returns></returns> public override bool ShouldRetry(Exception callError) { if (IsSocketOrRedisTimeOutException(callError)) { return(true); } System.AggregateException aggregateError = callError as System.AggregateException; if (null != aggregateError) { //this is kind of aggressive but you can replace it if you want to foreach (Exception innerError in aggregateError.InnerExceptions) { if (IsSocketOrRedisTimeOutException(innerError)) { return(true); } } } else { //this is kind of aggressive but you can replace it if you want to Exception innerException = callError.InnerException; while (null != innerException) { if (IsSocketOrRedisTimeOutException(innerException)) { return(true); } innerException = innerException.InnerException; } } return(false); }
public ExceptionViewModel(Exception exception) { DisplayName = "An unhandled exception occurred"; CloseCommand = new RelayCommand(TryClose); _exception = exception.Unwrap().ToAggregate(); }
private static AggregateException HandleRecursively( AggregateException aggregateException, Func<Exception, bool> predicate) { // Maintain a list of exceptions to be rethrown List<Exception> innerExceptions = null; // Loop over all of the inner exceptions foreach (var inner in aggregateException.InnerExceptions) { // If the inner exception is itself an aggregate, process recursively AggregateException innerAsAggregate = inner as AggregateException; if (innerAsAggregate != null) { // Process recursively, and if we get back a new aggregate, store it AggregateException newChildAggregate = HandleRecursively(innerAsAggregate, predicate); if (newChildAggregate != null) { if (innerExceptions != null) innerExceptions = new List<Exception>(); innerExceptions.Add(newChildAggregate); } } // Otherwise, if the exception does not match the filter, store it else if (!predicate(inner)) { if (innerExceptions != null) innerExceptions = new List<Exception>(); innerExceptions.Add(inner); } } // If there are any remaining exceptions, return them in a new aggregate. return innerExceptions.Count > 0 ? new AggregateException(aggregateException.Message, innerExceptions) : null; }
public void Stack_CreateFromAggregatedExceptionWithInnerException() { bool caughtException = false; try { File.Create(Path.GetInvalidFileNameChars()[0].ToString(), 0); } catch (ArgumentException exception) { var innerException1 = new InvalidOperationException("Test exception 1."); var innerException2 = new InvalidOperationException("Test exception 2.", exception); var aggregated = new AggregateException(innerException1, innerException2); IList<Stack> stacks = Stack.CreateStacks(aggregated).ToList(); stacks.Count.Should().Be(4); aggregated.StackTrace.Should().Be(null); Assert.AreEqual("[No frames]", stacks[0].ToString()); Assert.AreEqual("[No frames]", stacks[1].ToString()); Assert.AreEqual("[No frames]", stacks[2].ToString()); Assert.AreEqual(exception.StackTrace, stacks[3].ToString()); Assert.AreEqual(aggregated.FormatMessage(), stacks[0].Message); Assert.AreEqual(innerException1.FormatMessage(), stacks[1].Message); Assert.AreEqual(innerException2.FormatMessage(), stacks[2].Message); Assert.AreEqual(exception.FormatMessage(), stacks[3].Message); caughtException = true; } Assert.IsTrue(caughtException); }
private async Task<string> DoSomethingInPrivate() { LogTo.Error("After do somehting in private task"); var list = new List<Exception>() { new NullReferenceException(), new ArgumentNullException() }; var aggregate = new AggregateException(list); throw aggregate; }
protected IEnumerable <Exception> StripWrapperExceptions(Exception exception) { if (exception != null && _wrapperExceptions.Any(wrapperException => exception.GetType() == wrapperException && exception.InnerException != null)) { System.AggregateException aggregate = exception as System.AggregateException; if (aggregate != null) { foreach (Exception e in aggregate.InnerExceptions) { foreach (Exception ex in StripWrapperExceptions(e)) { yield return(ex); } } } else { foreach (Exception e in StripWrapperExceptions(exception.InnerException)) { yield return(e); } } } else { yield return(exception); } }
private void HandleAggregateException(AggregateException ex) { foreach (var innerException in ex.InnerExceptions) { _logger.Error("", innerException); } }
private static void HandleException(AggregateException ex) { foreach (var x in ex.InnerExceptions) { Console.WriteLine(x.Message); } }
public static void TraceAllErrors(string msg, AggregateException aggregateException) { foreach (Exception innerException in aggregateException.InnerExceptions) { Trace.TraceError("{0} Exception: {1}", msg, innerException); } }
public void ExceptionPropertySetterHandlesAggregateExceptionsWithMultipleNestedExceptionsAndTrimsAfterReachingMaxCount() { const int Overage = 5; List<Exception> innerExceptions = new List<Exception>(); for (int i = 0; i < Constants.MaxExceptionCountToSave + Overage; i++) { innerExceptions.Add(new Exception((i + 1).ToString(CultureInfo.InvariantCulture))); } AggregateException rootLevelException = new AggregateException("0", innerExceptions); ExceptionTelemetry telemetry = new ExceptionTelemetry { Exception = rootLevelException }; Assert.Equal(Constants.MaxExceptionCountToSave + 1, telemetry.Exceptions.Count); int counter = 0; foreach (ExceptionDetails details in telemetry.Exceptions.Take(Constants.MaxExceptionCountToSave)) { Assert.Equal(counter.ToString(CultureInfo.InvariantCulture), details.message); counter++; } ExceptionDetails first = telemetry.Exceptions.First(); ExceptionDetails last = telemetry.Exceptions.Last(); Assert.Equal(first.id, last.outerId); Assert.Equal(typeof(InnerExceptionCountExceededException).FullName, last.typeName); Assert.Equal( string.Format( CultureInfo.InvariantCulture, "The number of inner exceptions was {0} which is larger than {1}, the maximum number allowed during transmission. All but the first {1} have been dropped.", 1 + Constants.MaxExceptionCountToSave + Overage, Constants.MaxExceptionCountToSave), last.message); }
public void RaiseErrors() { if (exceptions.Count > 0) { AggregateException aggregate = new AggregateException(exceptions); throw aggregate; } }
public static void LogAggregateException(this ILog log, string message, AggregateException ex) { log.Error(message, ex); foreach (Exception e in ex.InnerExceptions) { log.Error(e); } }
public MessageDeserializationFailedQuarantinedEvent(AggregateException exceptions, string queueName, string storeName, Type messageType, byte[] data) { Exceptions = exceptions; QueueName = queueName; QuarantineStoreName = storeName; MessageType = messageType; Data = data; }
void GenerateAggregateError(IEnumerable<Exception> errors) { var message = new StringBuilder(); foreach (Exception ex in errors) { message.AppendLine(ex.Message); } Error = new AggregateException(message.ToString(), errors); }
public void An_insert_concurrency_exception_wrapped_in_an_exception_is_a_concurrency_exception() { var exception = new AggregateException( new DataException("Cannot insert duplicate key")); exception.IsConcurrencyException().Should().BeTrue(); }
public void An_insert_concurrency_exception_nested_deep_in_other_exceptions_is_a_concurrency_exception2() { var exception = new AggregateException( new AggregateException( new DataException("Cannot insert duplicate key"))); exception.IsConcurrencyException().Should().BeTrue(); }
internal static CastResult CastValueWithGeneratedCode(object value, Type sourceType, Type targetType, CastFlag castFlag) { string className = "GeneratedTestClass"; string methodName = "RunTest"; string castLine = string.Format( "{0} x = {1}value; return x;", targetType.GetFormattedFullname(), castFlag == CastFlag.Implicit ? string.Empty : "(" + targetType.GetFormattedFullname() + ")"); string code = "public class " + className + " { public " + targetType.GetFormattedFullname() + " " + methodName + "(" + sourceType.GetFormattedFullname() + " value)" + "{" + castLine + "}}"; using (CSharpCodeProvider provider = new CSharpCodeProvider()) { var compilerParams = new CompilerParameters(); compilerParams.ReferencedAssemblies.Add(typeof(CastTestRunner).Assembly.Location); compilerParams.GenerateExecutable = false; compilerParams.GenerateInMemory = true; var compilationResult = provider.CompileAssemblyFromSource(compilerParams, code); if (compilationResult.Errors.HasErrors) { var compilerException = new AggregateException("CastValueWithGeneratedCode failed to generate test class.", compilationResult.Errors .OfType<CompilerError>() .Where(e => !e.IsWarning) .Select(e => new CompilerException(e.Line, e.Column, e.ErrorText))); return new CastResult(compilerException, castFlag); } var generatedClass = compilationResult.CompiledAssembly.GetType(className); var instance = Activator.CreateInstance(generatedClass); var testMethod = generatedClass.GetMethod(methodName); try { var castedValue = testMethod.Invoke(instance, new[] { value }); return new CastResult(castedValue, castFlag); } catch (TargetInvocationException ex) { if (ex.InnerException is InvalidProgramException) { // This is most probably an error in Roslyn compiler. // See http://stackoverflow.com/questions/18342943/serious-bugs-with-lifted-nullable-conversions-from-int-allowing-conversion-from return new CastResult(value, castFlag); } return new CastResult(ex, castFlag); } catch (Exception ex) { return new CastResult(ex, castFlag); } } }
public void ThrowIfNeeded() { if (list.Count == 0) return; var aggregateException = new AggregateException(list); log.Log(level, () => errorMsg, aggregateException); throw aggregateException; }
public void ThrowIfNeeded() { if (list.Count == 0) return; var aggregateException = new AggregateException(list); throw aggregateException; }
public void ShouldSerializeAggregateExceptionToString() { var e = new System.AggregateException("test", new[] { new System.Exception("test2"), new System.Exception("test3") }); e.AsString().Should().ContainAll("test", "test2", "test3"); }
private static String concatMessages(AggregateException ae) { if (ae == null) { return ""; } var flattened = ae.Flatten(); return String.Join("\n\n", from exc in flattened.InnerExceptions select getExceptionMessages("", exc)); }
private static string GetStackForAggregateException(Exception exception, AggregateException aggregate) { var text = GetStackForException(exception, true); for (int i = 0; i < aggregate.InnerExceptions.Count; i++) { text = string.Format("{0}{1}---> (Inner Exception #{2}) {3}{4}{5}", text, Environment.NewLine, i, GetFormattedExceptionStack(aggregate.InnerExceptions[i]), "<---", Environment.NewLine); } return text; }
/// <summary> /// If inner exceptions contain RpcException, rethrows it. /// Otherwise, rethrows the original aggregate exception. /// Always throws, the exception return type is here only to make the. /// </summary> public static Exception UnwrapRpcException(AggregateException ae) { foreach (var e in ae.InnerExceptions) { if (e is RpcException) { throw e; } } throw ae; }
private PortalException HandleAggregateException(System.AggregateException aggregateException) { ResourceProviderClientException exception = aggregateException.InnerException as ResourceProviderClientException; if (exception != null) { return(new PortalException(exception.Message, exception.HttpStatusCode)); } return(new PortalException(aggregateException.InnerException.Message, aggregateException.InnerException, System.Net.HttpStatusCode.InternalServerError)); }
protected override void OnTaskFault(AggregateException exception) { base.OnTaskFault(exception); #if DEBUG if (SystemInspector.Debugger.IsAttached) { Application.Current.Sync().Execute(() => { throw exception; }); } #endif }
private static Exception _createAggregateException(Exception[] aggregateExceptions) { Exception aggregateException; if (aggregateExceptions.Length == 1) aggregateException = aggregateExceptions[0]; else if (aggregateExceptions.Length > 0) aggregateException = new AggregateException(aggregateExceptions); else aggregateException = null; return aggregateException; }
public System.AggregateException GetExceptions() { if (this.Exceptions.Count == 0) { return(null); } System.AggregateException agg = new System.AggregateException( "Aggregated exceptions from DatasetMultiResult", Exceptions ); return(agg); }
/// <summary> /// Returns the <see cref="System.AggregateException"/> that is the root cause of this exception. /// </summary> public override Exception GetBaseException() { // Returns the first inner AggregateException that contains more or less than one inner exception // Recursively traverse the inner exceptions as long as the inner exception of type AggregateException and has only one inner exception Exception back = this; AggregateException backAsAggregate = this; while (backAsAggregate != null && backAsAggregate.InnerExceptions.Count == 1) { back = back.InnerException; backAsAggregate = back as AggregateException; } return(back); }
// // Methods // public AggregateException Flatten() { List <Exception> list = new List <Exception>(); foreach (Exception current in this.InnerExceptions) { AggregateException ex = current as AggregateException; if (ex != null) { list.AddRange(ex.Flatten().InnerExceptions); } else { list.Add(current); } } return(new AggregateException(list)); }
/// <summary> /// Flattens an <see cref="AggregateException"/> instances into a single, new instance. /// </summary> /// <returns>A new, flattened <see cref="AggregateException"/>.</returns> /// <remarks> /// If any inner exceptions are themselves instances of /// <see cref="AggregateException"/>, this method will recursively flatten all of them. The /// inner exceptions returned in the new <see cref="AggregateException"/> /// will be the union of all of the the inner exceptions from exception tree rooted at the provided /// <see cref="AggregateException"/> instance. /// </remarks> public AggregateException Flatten() { // Initialize a collection to contain the flattened exceptions. LowLevelListWithIList <Exception> flattenedExceptions = new LowLevelListWithIList <Exception>(); // Create a list to remember all aggregates to be flattened, this will be accessed like a FIFO queue LowLevelList <AggregateException> exceptionsToFlatten = new LowLevelList <AggregateException>(); exceptionsToFlatten.Add(this); int nDequeueIndex = 0; // Continue removing and recursively flattening exceptions, until there are no more. while (exceptionsToFlatten.Count > nDequeueIndex) { // dequeue one from exceptionsToFlatten IList <Exception> currentInnerExceptions = exceptionsToFlatten[nDequeueIndex++].InnerExceptions; for (int i = 0; i < currentInnerExceptions.Count; i++) { Exception currentInnerException = currentInnerExceptions[i]; if (currentInnerException == null) { continue; } AggregateException currentInnerAsAggregate = currentInnerException as AggregateException; // If this exception is an aggregate, keep it around for later. Otherwise, // simply add it to the list of flattened exceptions to be returned. if (currentInnerAsAggregate != null) { exceptionsToFlatten.Add(currentInnerAsAggregate); } else { flattenedExceptions.Add(currentInnerException); } } } return(new AggregateException(Message, flattenedExceptions)); }
public AggregateException Flatten() { List <Exception> inner = new List <Exception> (); foreach (Exception e in innerExceptions) { AggregateException aggEx = e as AggregateException; if (aggEx != null) { inner.AddRange(aggEx.Flatten().InnerExceptions); } else { inner.Add(e); } } return(new AggregateException(inner)); }
public override Exception GetBaseException() { AggregateException result = this; while (true) { Exception item; if (result._innerExceptions.Count != 1 || ReferenceEquals(null, item = result._innerExceptions[0])) { return(result); } var tmp = item as AggregateException; if (tmp == null) { return(item); } result = tmp; } }
public static string GetDetails(this Exception exception, int indent = 0) { Throw <ArgumentNullException> .WhenObject.IsNull(() => exception); StringBuilder message = new StringBuilder(); message.AppendLine(IndentText(exception.Message, indent)); if (!string.IsNullOrWhiteSpace(exception.StackTrace)) { message.AppendLine(IndentText("StackTrace:", indent)); message.AppendLine(IndentText(exception.StackTrace, indent)); } AggregateException aggregateException = exception as AggregateException; if (aggregateException != null) { message.AppendLine(IndentText("InnerExceptions:", indent)); foreach (var innerException in aggregateException.InnerExceptions) { message.AppendLine(IndentText(GetDetails(innerException, indent + 1), indent)); } } else if (exception is FaultException <ExceptionDetail> ) { var faultException = (FaultException <ExceptionDetail>)exception; message.AppendLine(IndentText("Detail:", indent)); if (faultException.Detail != null) { message.AppendLine(IndentText(GetDetails(faultException.Detail, indent + 1), indent)); } } else if (exception.InnerException != null) { message.AppendLine(IndentText("InnerException:", indent)); message.AppendLine(IndentText(GetDetails(exception.InnerException, indent + 1), indent)); } return(message.ToString().Trim('\r', '\n')); }
public void Can_Timeout_PUT_TaskAsync() { const string baseUrl = "http://localhost:8080/"; using (SimpleServer.Create(baseUrl, Handlers.Generic <ResponseHandler>())) { var client = new RestClient(baseUrl); var request = new RestRequest("timeout", Method.PUT).AddBody("Body_Content"); //Half the value of ResponseHandler.Timeout request.Timeout = 500; System.AggregateException agg = Assert.Throws <System.AggregateException>( delegate { var task = client.ExecuteTaskAsync(request); task.Wait(); }); Assert.IsType(typeof(WebException), agg.InnerException); Assert.Equal("The request timed-out.", agg.InnerException.Message); } }
public AggregateException Flatten() { var inner = new List <Exception>(); var queue = new Queue <AggregateException>(); queue.Enqueue(this); while (queue.Count > 0) { AggregateException current = queue.Dequeue(); foreach (var exception in current._innerExceptions) { var aggregatedException = exception as AggregateException; if (aggregatedException != null) { queue.Enqueue(aggregatedException); } else { inner.Add(exception); } } } return(new AggregateException(inner)); }
private static void Suppose_UnsupportedType(System.AggregateException p1) { }
public void Invoke(IncomingContext context, Action next) { Stopwatch s = null; var uows = new ConcurrentStack <ICommandUnitOfWork>(); try { _commandsMeter.Mark(); using (_commandsTimer.NewContext()) { context.Builder.BuildAll <ICommandUnitOfWork>().ForEachAsync(2, async(uow) => { uows.Push(uow); uow.Builder = context.Builder; await uow.Begin(); }).Wait(); if (Logger.IsDebugEnabled) { s = Stopwatch.StartNew(); } next(); if (Logger.IsDebugEnabled) { s.Stop(); Logger.DebugFormat("Processing command {0} took {1} ms", context.IncomingLogicalMessage.MessageType.FullName, s.ElapsedMilliseconds); s.Restart(); } uows.Generate().ForEachAsync(2, async(uow) => { try { await uow.End(); } catch { // If it failed it needs to go back on the stack uows.Push(uow); throw; } }).Wait(); if (Logger.IsDebugEnabled) { s.Stop(); Logger.DebugFormat("UOW.End for command {0} took {1} ms", context.IncomingLogicalMessage.MessageType.FullName, s.ElapsedMilliseconds); } } } catch (System.AggregateException e) { _errorsMeter.Mark(); var trailingExceptions = new List <Exception>(); uows.Generate().ForEachAsync(2, async(uow) => { try { await uow.End(e); } catch (Exception endException) { trailingExceptions.Add(endException); } }).Wait(); if (trailingExceptions.Any()) { trailingExceptions.Insert(0, e); e = new System.AggregateException(trailingExceptions); } throw; } }
// Todo: all the logging and timing can be moved into a "Debug Dispatcher" which can be registered as the IDispatcher if the user wants private async Task Process(Object @event, IEventDescriptor descriptor = null, long?position = null) { var eventType = _mapper.GetMappedTypeFor(@event.GetType()); Stopwatch s = null; var handleContext = new HandleContext { Bus = _bus, EventDescriptor = descriptor }; using (_eventsTimer.NewContext()) { if (Logger.IsDebugEnabled) { Logger.DebugFormat("Processing event {0} at position {1}. Size of queue: {2}/{3}", eventType.FullName, position, _processingQueueSize, _maxQueueSize); } using (var childBuilder = _builder.CreateChildBuilder()) { var handlerGenericType = typeof(IHandleMessagesAsync <>).MakeGenericType(eventType); List <dynamic> handlers = childBuilder.BuildAll(handlerGenericType).ToList(); if (handlers.Count == 0) { return; } var success = false; var retry = 0; do { var uows = new ConcurrentStack <IEventUnitOfWork>(); var mutators = childBuilder.BuildAll <IEventMutator>(); if (Logger.IsDebugEnabled) { s = Stopwatch.StartNew(); } if (mutators != null && mutators.Any()) { Parallel.ForEach(mutators, _parallelOptions, mutate => { //if (Logger.IsDebugEnabled) Logger.DebugFormat("Mutating incoming event {0} with mutator {1}", eventType.FullName, mutate.GetType().FullName); @event = mutate.MutateIncoming(@event, descriptor, position); }); } await childBuilder.BuildAll <IEventUnitOfWork>().ForEachAsync(2, async(uow) => { uows.Push(uow); uow.Builder = childBuilder; await uow.Begin(); }); if (Logger.IsDebugEnabled) { s.Stop(); Logger.DebugFormat("UOW.Begin for event {0} took {1} ms", eventType.FullName, s.ElapsedMilliseconds); } try { if (Logger.IsDebugEnabled) { s.Restart(); } Func <dynamic, Task> processor = async(handler) => { using (_handlerTimer.NewContext()) { var handlerRetries = 0; var handlerSuccess = false; do { try { Stopwatch handlerWatch = null; if (Logger.IsDebugEnabled) { Logger.DebugFormat("Executing event {0} on handler {1}", eventType.FullName, handler.GetType().FullName); handlerWatch = Stopwatch.StartNew(); } var lambda = _objectInvoker.Invoker(handler, eventType); await lambda(handler, @event, handleContext); if (Logger.IsDebugEnabled) { handlerWatch.Stop(); Logger.DebugFormat("Executing event {0} on handler {1} took {2} ms", eventType.FullName, handler.GetType().FullName, handlerWatch.ElapsedMilliseconds); } handlerSuccess = true; } catch (RetryException e) { Logger.InfoFormat("Received retry signal while dispatching event {0} to {1}. Retry: {2}/3\nException: {3}", eventType.FullName, handler.FullName, handlerRetries, e); handlerRetries++; } } while (!handlerSuccess && (_maxRetries == -1 || handlerRetries <= _maxRetries)); if (!handlerSuccess) { Logger.ErrorFormat("Failed executing event {0} on handler {1}", eventType.FullName, handler.FullName); throw new RetryException(String.Format("Failed executing event {0} on handler {1}", eventType.FullName, handler.FullName)); } } }; // Run each handler in parallel (or not) (if handler ever is ASYNC can't use Parallel) if (_parallelHandlers) { await handlers.ForEachAsync(_parallelOptions.MaxDegreeOfParallelism, processor); } else { foreach (var handler in handlers) { await processor(handler); } } if (Logger.IsDebugEnabled) { s.Stop(); Logger.DebugFormat("Processing event {0} took {1} ms", eventType.FullName, s.ElapsedMilliseconds); } } catch (Exception e) { var trailingExceptions = new ConcurrentBag <Exception>(); await uows.Generate().ForEachAsync(2, async(uow) => { try { await uow.End(e); } catch (Exception endException) { trailingExceptions.Add(endException); } }); if (trailingExceptions.Any()) { var exceptions = trailingExceptions.ToList(); exceptions.Insert(0, e); e = new System.AggregateException(exceptions); } // Only log if the event has failed more than half max retries indicating a possible non-transient error if (retry > (_maxRetries / 2)) { Logger.InfoFormat("Encountered an error while processing {0}. Retry {1}/{2}\nPayload: {3}\nException details:\n{4}", eventType.FullName, retry, _maxRetries, JsonConvert.SerializeObject(@event), e); } else { Logger.DebugFormat("Encountered an error while processing {0}. Retry {1}/{2}\nPayload: {3}\nException details:\n{4}", eventType.FullName, retry, _maxRetries, JsonConvert.SerializeObject(@event), e); } _errorsMeter.Mark(); retry++; Thread.Sleep(10); continue; } // Failures when executing UOW.End `could` be transient (network or disk hicup) // A failure of 1 uow in a chain of 5 is a problem as it could create a mangled DB (partial update via one uow then crash) // So we'll just keep retrying the failing UOW forever until it succeeds. if (Logger.IsDebugEnabled) { s.Restart(); } var endSuccess = false; var endRetry = 0; while (!endSuccess) { try { await uows.Generate().ForEachAsync(2, async(uow) => { try { await uow.End(); } catch { // If it failed it needs to go back on the stack uows.Push(uow); throw; } }); endSuccess = true; } catch (Exception e) { if (endRetry > (_maxRetries / 2)) { Logger.ErrorFormat("UOW.End failure while processing event {0} - retry {1}/{3}\nException:\n{2}", eventType.FullName, retry, e, _maxRetries); } else { Logger.DebugFormat("UOW.End failure while processing event {0} - retry {1}/{3}\nException:\n{2}", eventType.FullName, retry, e, _maxRetries); } endRetry++; Thread.Sleep(50); } } if (Logger.IsDebugEnabled) { s.Stop(); Logger.DebugFormat("UOW.End for event {0} took {1} ms", eventType.FullName, s.ElapsedMilliseconds); } success = true; } while (!success && (_maxRetries == -1 || retry < _maxRetries)); if (!success) { var message = String.Format("Encountered an error while processing {0}. Ran out of retries, dropping event.\nPayload: {3}", eventType.FullName, JsonConvert.SerializeObject(@event)); if (_dropEventFatal) { Logger.Fatal(message); throw new SubscriptionCanceled(message); } Logger.Error(message); } } } _eventsMeter.Mark(); }
public static string DisplayMessage(System.AggregateException exception) { throw null; }