Esempio n. 1
0
        public async Task<HandlerResponse> ExecuteAsync(CancellationToken cancellationToken)
        {
            ExceptionDispatchInfo exceptionInfo;

            try
            {
                return await this.innerResult.ExecuteAsync(cancellationToken);
            }
            catch (Exception e)
            {
                exceptionInfo = ExceptionDispatchInfo.Capture(e);
            }

            // This code path only runs if the task is faulted with an exception
            Exception exception = exceptionInfo.SourceException;
            bool isCancellationException = exception is OperationCanceledException;

            ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo, ExceptionCatchBlocks.ExceptionFilter, this.context);

            if (!isCancellationException)   
            {   
                // We don't log cancellation exceptions because it doesn't represent an error.   
                await this.exceptionLogger.LogAsync(exceptionContext, cancellationToken);   
            }  
            
            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(this.context, exceptionInfo);

            // Note: exception filters need to be scheduled in the reverse order so that
            // the more specific filter (e.g. Action) executes before the less specific ones (e.g. Global)
            for (int i = this.filters.Length - 1; i >= 0; i--)
            {
                IExceptionFilter exceptionFilter = this.filters[i];
                await exceptionFilter.ExecuteExceptionFilterAsync(executedContext, cancellationToken);
            }

            if (executedContext.Response == null && !isCancellationException)
            {
                // We don't log cancellation exceptions because it doesn't represent an error. 
                executedContext.Response = await this.exceptionHandler.HandleAsync(exceptionContext, cancellationToken);
            }

            if (executedContext.Response != null)
            {
                return executedContext.Response;
            }

            // Preserve the original stack trace when the exception is not changed by any filter.
            if (exception == executedContext.ExceptionInfo.SourceException)
            {
                exceptionInfo.Throw();
            }
            else
            {
                // If the exception is changed by a filter, throw the new exception instead.
                executedContext.ExceptionInfo.Throw();
            }

            throw Error.InvalidOperation(Resources.UnreachableCode);
        }
Esempio n. 2
0
 public override void OnException(CommandHandlerExecutedContext handlerExecutedContext)
 {
     base.OnException(handlerExecutedContext);
     if (this.handle)
     {
         handlerExecutedContext.Response = handlerExecutedContext.Request.CreateResponse();
         Trace.WriteLine("Exception handled by  " + this.name);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Asynchronously executes the exception filter.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>An asynchronous exception filter.</returns>
        public Task ExecuteExceptionFilterAsync(CommandHandlerExecutedContext handlerExecutedContext, CancellationToken cancellationToken)
        {
            if (handlerExecutedContext == null)
            {
                throw Error.ArgumentNull("handlerExecutedContext");
            }

            this.OnException(handlerExecutedContext);
            return TaskHelpers.Completed();
        }
Esempio n. 4
0
        /// <summary>
        /// Asynchronously executes the exception filter.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>An asynchronous exception filter.</returns>
        public Task ExecuteExceptionFilterAsync(CommandHandlerExecutedContext handlerExecutedContext, CancellationToken cancellationToken)
        {
            if (handlerExecutedContext == null)
            {
                throw Error.ArgumentNull("handlerExecutedContext");
            }

            this.OnException(handlerExecutedContext);
            return(TaskHelpers.Completed());
        }
        public virtual Task OnCommandExecutedAsync(CommandHandlerExecutedContext handlerExecutedContext, CancellationToken cancellationToken)
        {
            try
            {
                this.OnCommandExecuted(handlerExecutedContext);
            }
            catch (Exception ex)
            {
                return TaskHelpers.FromError(ex);
            }

            return TaskHelpers.Completed();
        }
Esempio n. 6
0
        /// <summary>
        /// Occurs after the handle method is invoked.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        public override void OnCommandExecuted(CommandHandlerExecutedContext handlerExecutedContext)
        {
            if (handlerExecutedContext == null)
            {
                throw new ArgumentNullException("handlerExecutedContext");
            }

            Stack<IDisposable> stack = GetStack(handlerExecutedContext.HandlerContext);
            if (stack != null && stack.Count > 0)
            {
                IDisposable disposable = stack.Pop();
                disposable.Dispose();
            }
        }
        public void WhenSettingResultThenResultIsDefined()
        {
            // Arrange
            CommandHandlerContext preContext = new CommandHandlerContext();
            Exception exception = new Exception();
            ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception);
            CommandHandlerExecutedContext context = new CommandHandlerExecutedContext(preContext, exceptionInfo);
            var value = "test";

            // Act
            context.Response = context.Request.CreateResponse("test");

            // Assert
            Assert.Equal(context.Response.Value, value);
        }
        public void WhenCreatingInstanceThenPropertiesAreDefined()
        {
            // Arrange
            CommandHandlerContext preContext = new CommandHandlerContext();
            Exception exception = new Exception();
            ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception);

            // Act
            CommandHandlerExecutedContext context = new CommandHandlerExecutedContext(preContext, exceptionInfo);

            // Assert
            Assert.Null(context.Response);
            Assert.NotNull(context.ExceptionInfo.SourceException);
            Assert.Same(context.ExceptionInfo.SourceException, exception);
        }
        public void WhenInvokingFilterWithExceptionThenTransactionRollbacks()
        {
            // Arrange
            TransactionFilterAttribute filter = new TransactionFilterAttribute();
            CommandHandlerContext executingContext = new CommandHandlerContext();
            Exception exception = new Exception();
            ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception);
            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(executingContext, exceptionInfo);

            // Act
            filter.OnCommandExecuting(executingContext);
            Transaction transaction = Transaction.Current.Clone();
            filter.OnCommandExecuted(executedContext);

            // Assert
            Assert.Equal(TransactionStatus.Aborted, transaction.TransactionInformation.Status);
        }
        public void WhenInvokingFilterWithoutExceptionThenTransactionCompletes()
        {
            // Arrange
            TransactionFilterAttribute filter = new TransactionFilterAttribute();
            HandlerRequest request = new HandlerRequest(this.config, null);
            CommandHandlerContext executingContext = new CommandHandlerContext();

            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(executingContext, null);
            executingContext.Response = new HandlerResponse(null);

            // Act
            filter.OnCommandExecuting(executingContext);
            Transaction transaction = Transaction.Current.Clone();
            filter.OnCommandExecuted(executedContext);

            // Assert 
            Assert.Equal(TransactionStatus.Committed, transaction.TransactionInformation.Status);
        }
Esempio n. 11
0
        /// <summary>
        /// Occurs after the handle method is invoked.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        public override void OnCommandExecuted(CommandHandlerExecutedContext handlerExecutedContext)
        {
            if (handlerExecutedContext == null)
            {
                throw Error.ArgumentNull("handlerExecutedContext");
            }

            Stack<TransactionScope> stack = GetStack(handlerExecutedContext.HandlerContext);
            if (stack != null && stack.Count > 0)
            {
                using (var scope = stack.Pop())
                {
                    if (null != scope && handlerExecutedContext.Response != null)
                    {
                        scope.Complete();
                    }
                }
            }
        }
        public void WhenExecuteExceptionFilterAsyncThenReturnsCompletedTask()
        {
            // Arrange
            Mock<MessageProcessorTests.ISpy> spy = new Mock<MessageProcessorTests.ISpy>();
            IExceptionFilter filter = new CustomExceptionFilterAttribute(spy.Object);
            CommandHandlerContext handlerContext = new CommandHandlerContext();
            Exception exception = new Exception();
            ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception);
            CommandHandlerExecutedContext handlerExecutedContext = new CommandHandlerExecutedContext(handlerContext, exceptionInfo);
            CancellationToken cancellationToken = new CancellationToken();

            // Act
            var task = filter.ExecuteExceptionFilterAsync(handlerExecutedContext, cancellationToken);

            // Assert
            Assert.NotNull(task);
            Assert.True(task.IsCompleted);
            spy.Verify(s => s.Spy("OnException"), Times.Once());
        }
Esempio n. 13
0
        /// <summary>
        /// Occurs after the handle method is invoked.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        public override void OnCommandExecuted(CommandHandlerExecutedContext handlerExecutedContext)
        {
            if (handlerExecutedContext == null)
            {
                throw Error.ArgumentNull("handlerExecutedContext");
            }

            Stack <TransactionScope> stack = GetStack(handlerExecutedContext.HandlerContext);

            if (stack != null && stack.Count > 0)
            {
                using (var scope = stack.Pop())
                {
                    if (null != scope && handlerExecutedContext.Response != null)
                    {
                        scope.Complete();
                    }
                }
            }
        }
Esempio n. 14
0
        public void WhenExecutedFilterVaryByParamsSetIncorrectlyThenCacheIsAlwaysUsed()
        {
            // Arrange
            CacheAttribute filter = this.CreateAttribute(new MemoryCache("test"));
            filter.Duration = 10;
            filter.VaryByParams = "XXXX";

            CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler));
            SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" };
            CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1);
            CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor);
            CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null);
            executedContext1.SetResponse("result1");

            SimpleCommand command2 = new SimpleCommand { Property1 = 2, Property2 = "test2" };
            CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2);
            CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor);
            CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null);
            executedContext2.SetResponse( "result2");

            SimpleCommand command3 = new SimpleCommand { Property1 = 2, Property2 = "test3" };
            CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3);
            CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor);
            CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null);
            executedContext3.SetResponse("result3");

            // Act
            filter.OnCommandExecuting(context1);
            filter.OnCommandExecuted(executedContext1);
            filter.OnCommandExecuting(context2);
            filter.OnCommandExecuted(executedContext2);
            filter.OnCommandExecuting(context3);
            filter.OnCommandExecuted(executedContext3);

            // Assert
            Assert.Equal("result1", executedContext1.Response.Value);
            Assert.Equal("result1", executedContext2.Response.Value);
            Assert.Equal("result1", executedContext3.Response.Value);
        }
Esempio n. 15
0
        public void WhenExecutedFilterWithKeyThenCacheIsUpdated()
        {
            // Arrange
            CacheAttribute filter = this.CreateAttribute();
            SimpleCommand command = new SimpleCommand { Property1 = 12, Property2 = "test" };
            CommandHandlerRequest request = new CommandHandlerRequest(this.config, command);
            CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler));
            CommandHandlerContext context = new CommandHandlerContext(request, descriptor);
            filter.OnCommandExecuting(context);

            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(context, null);

            // Act
            filter.OnCommandExecuted(executedContext);

            // Assert
            this.cache.Verify(c => c.Add(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<DateTimeOffset>(), It.IsAny<string>()), Times.Once());
        }
Esempio n. 16
0
        public void WhenExecutedFilterToIgnoreThenCacheIsIgnored()
        {
            // Arrange
            CacheAttribute filter = this.CreateAttribute();
            SimpleCommand command = new SimpleCommand { Property1 = 12, Property2 = "test" };
            SimpleCommand cachedCommand = new SimpleCommand { Property1 = 12, Property2 = "test in cache" };
            CommandHandlerRequest request = new CommandHandlerRequest(this.config, command);
            CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(NotCachedCommand), typeof(NotCachedCommandHandler));
            CommandHandlerContext context = new CommandHandlerContext(request, descriptor);
            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(context, null);
            this.cache.Setup(c => c.Get(It.IsAny<string>(), It.IsAny<string>())).Returns(new CacheAttribute.CacheEntry(cachedCommand));

            // Act
            filter.OnCommandExecuted(executedContext);

            // Assert
            this.cache.Verify(c => c.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
            Assert.Null(context.Response);
        }
 public override void OnException(CommandHandlerExecutedContext handlerExecutedContext)
 {
     this.spy.Spy("OnException");
     base.OnException(handlerExecutedContext);
 }
 /// <summary>
 /// Occurs after the handle method is invoked.
 /// </summary>
 /// <param name="handlerExecutedContext">The handler executed context.</param>
 /// <remarks>
 /// Overrides this method to add a behaviour after a command in a non-asynchronous way.
 /// </remarks>
 public virtual void OnCommandExecuted(CommandHandlerExecutedContext handlerExecutedContext)
 {
 }
Esempio n. 19
0
        public void WhenExecutedFilterVaryByUserThenCacheIsUpdated()
        {
            // Arrange
            CacheAttribute filter = this.CreateAttribute(new MemoryCache("test"));
            filter.Duration = 10;
            filter.VaryByUser = true;
            filter.VaryByParams = CacheAttribute.VaryByParamsNone;

            CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler));
            SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" };
            CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1);
            CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor);
            context1.User = new GenericPrincipal(new GenericIdentity("user1"), null);
            CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null);
            executedContext1.Response = new HandlerResponse(request1, "result1");

            SimpleCommand command2 = new SimpleCommand { Property1 = 1, Property2 = "test1" };
            CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2);
            CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor);
            context2.User = new GenericPrincipal(new GenericIdentity("user2"), null);
            CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null);
            executedContext2.Response = new HandlerResponse(request2, "result2");

            SimpleCommand command3 = new SimpleCommand { Property1 = 1, Property2 = "test1" };
            CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3);
            CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor);
            context3.User = new GenericPrincipal(new GenericIdentity("user1"), null);
            CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null);
            executedContext3.Response = new HandlerResponse(request3, "result3");

            // Act
            filter.OnCommandExecuting(context1);
            filter.OnCommandExecuted(executedContext1);
            filter.OnCommandExecuting(context2);
            filter.OnCommandExecuted(executedContext2);
            filter.OnCommandExecuting(context3);
            filter.OnCommandExecuted(executedContext3);

            // Assert
            Assert.Equal("result1", executedContext1.Response.Value);
            Assert.Equal("result2", executedContext2.Response.Value);
            Assert.Equal("result1", executedContext3.Response.Value);
        }
Esempio n. 20
0
 /// <summary>
 /// Raises the exception event.
 /// </summary>
 /// <param name="handlerExecutedContext">The context for the handler..</param>
 public virtual void OnException(CommandHandlerExecutedContext handlerExecutedContext)
 {
 }
Esempio n. 21
0
        public void WhenExecutedFilterWithExceptionThenCacheIsNotUpdated()
        {
            // Arrange
            CacheAttribute filter = this.CreateAttribute();
            SimpleCommand command = new SimpleCommand { Property1 = 12, Property2 = "test" };
            CommandHandlerRequest request = new CommandHandlerRequest(this.config, command);
            CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler));
            CommandHandlerContext context = new CommandHandlerContext(request, descriptor);
            Exception exception = new Exception();
            ExceptionDispatchInfo exceptionInfo = ExceptionDispatchInfo.Capture(exception);
            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(context, exceptionInfo);

            // Act
            filter.OnCommandExecuted(executedContext);

            // Assert
            this.cache.Verify(c => c.Add(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<DateTimeOffset>(), It.IsAny<string>()), Times.Never());
            Assert.Null(context.Response);
        }
Esempio n. 22
0
 /// <summary>
 /// Raises the exception event.
 /// </summary>
 /// <param name="handlerExecutedContext">The context for the handler..</param>
 public virtual void OnException(CommandHandlerExecutedContext handlerExecutedContext)
 {
 }
Esempio n. 23
0
        /// <summary>
        /// Occurs after the handle method is invoked.
        /// </summary>
        /// <param name="handlerExecutedContext">The handler executed context.</param>
        public override void OnCommandExecuted(CommandHandlerExecutedContext handlerExecutedContext)
        {
            if (handlerExecutedContext == null)
            {
                throw Error.ArgumentNull("handlerExecutedContext");
            }

            if (handlerExecutedContext.ExceptionInfo != null)
            {
                return;
            }

            if (ShouldIgnoreCache(handlerExecutedContext.HandlerContext.Descriptor))
            {
                return;
            }
            
            if (!handlerExecutedContext.HandlerContext.Items.ContainsKey(CacheKey))
            {
                return;
            }

            string key = handlerExecutedContext.HandlerContext.Items[CacheKey] as string;
            if (key == null)
            {
                return;
            }

            DateTimeOffset expiration = this.CreateExpiration();

            CacheEntry entry = handlerExecutedContext.Response == null ? CacheEntry.Empty : new CacheEntry(handlerExecutedContext.Response.Value);
            this.cache.Add(key, entry, expiration); 
        }
        private async Task<HandlerResponse> CallOnHandlerExecutedAsync(CommandHandlerContext handlerContext, CancellationToken cancellationToken, Func<Task<HandlerResponse>> continuation)
        {
            cancellationToken.ThrowIfCancellationRequested();

            HandlerResponse response = null;
            ExceptionDispatchInfo exceptionInfo = null;
            try
            {
                response = await continuation();
            }
            catch (Exception e)
            {
                exceptionInfo = ExceptionDispatchInfo.Capture(e);
            }

            CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(handlerContext, exceptionInfo)
            {
                Response = response
            };

            try
            {
                await this.OnCommandExecutedAsync(executedContext, cancellationToken);
            }
            catch
            {
                // Catch is running because OnCommandExecuted threw an exception, so we just want to re-throw.
                // We also need to reset the response to forget about it since a filter threw an exception.
                handlerContext.Response = null;
                throw;
            }

            if (executedContext.Response != null)
            {
                return executedContext.Response;
            }

            if (executedContext.ExceptionInfo != null)
            {
                if (exceptionInfo == null)
                {
                    executedContext.ExceptionInfo.Throw();
                }
                else
                {
                    Exception newException = executedContext.ExceptionInfo.SourceException;
                    Exception exception = exceptionInfo.SourceException;
                    if (newException == exception)
                    {
                        exceptionInfo.Throw();
                    }
                    else
                    {
                        executedContext.ExceptionInfo.Throw();
                    }
                }
            }

            throw Error.InvalidOperation(Resources.HandlerFilterAttribute_MustSupplyResponseOrException, this.GetType().Name);
        }