public void NotifyAsync() { Should.Throw <ArgumentNullException>(() => new ExceptionNotifier(null)); var factory = Substitute.For <IHybridServiceScopeFactory>(); var scope = Substitute.For <IServiceScope>(); var subscriber = Substitute.For <IExceptionSubscriber>(); var provider = Substitute.For <IServiceProvider>(); scope.Configure().ServiceProvider.Returns(provider); provider.Configure().GetService(typeof(IEnumerable <IExceptionSubscriber>)).Returns(new List <IExceptionSubscriber> { subscriber }); factory.Configure().CreateScope().Returns(scope); var notifier = Should.NotThrow(() => new ExceptionNotifier(factory)); var context = new ExceptionNotificationContext(new ScorpioException()); Should.NotThrow(() => notifier.NotifyAsync(context)); subscriber.Received(1).HandleAsync(context); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> public virtual async Task NotifyAsync(ExceptionNotificationContext context) { Check.NotNull(context, nameof(context)); using (var scope = ServiceScopeFactory.CreateScope()) { var exceptionSubscribers = scope.ServiceProvider .GetServices <IExceptionSubscriber>(); foreach (var exceptionSubscriber in exceptionSubscribers) { try { await exceptionSubscriber.HandleAsync(context); } catch (Exception e) { Logger.LogWarning($"Exception subscriber of type {exceptionSubscriber.GetType().AssemblyQualifiedName} has thrown an exception!"); Logger.LogException(e, LogLevel.Warning); } } } }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> public Task NotifyAsync(ExceptionNotificationContext context) => Task.CompletedTask;
/// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> public abstract Task HandleAsync(ExceptionNotificationContext context);