Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Add ExceptionHandled to ExceptionContext
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanbrandenburg committed Jun 9, 2016
1 parent 8c8fd64 commit 27bde12
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public virtual ExceptionDispatchInfo ExceptionDispatchInfo
}
}

/// <summary>
/// Gets or sets an indication that the <see cref="Exception"/> has been handled.
/// </summary>
public virtual bool ExceptionHandled { get; set; } = false;

/// <summary>
/// Gets or sets the <see cref="IActionResult"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.Mvc.Internal
Expand Down Expand Up @@ -354,7 +353,7 @@ private async Task InvokeResourceFilterAsync()
Result = _exceptionContext.Result,
};
}
else if (_exceptionContext.Exception != null)
else if (_exceptionContext.Exception != null && !_exceptionContext.ExceptionHandled)
{
// If we get here, this means that we have an unhandled exception.
// Exception filted didn't handle this, so send it on to resource filters.
Expand Down Expand Up @@ -412,7 +411,7 @@ private async Task InvokeExceptionFilterAsync()
await InvokeExceptionFilterAsync();

Debug.Assert(_exceptionContext != null);
if (_exceptionContext.Exception != null)
if (_exceptionContext.Exception != null && !_exceptionContext.ExceptionHandled)
{
_diagnosticSource.BeforeOnExceptionAsync(_exceptionContext, current.FilterAsync);

Expand All @@ -422,7 +421,7 @@ private async Task InvokeExceptionFilterAsync()

_diagnosticSource.AfterOnExceptionAsync(_exceptionContext, current.FilterAsync);

if (_exceptionContext.Exception == null)
if (_exceptionContext.Exception == null || _exceptionContext.ExceptionHandled)
{
_logger.ExceptionFilterShortCircuited(current.FilterAsync);
}
Expand All @@ -435,7 +434,7 @@ private async Task InvokeExceptionFilterAsync()
await InvokeExceptionFilterAsync();

Debug.Assert(_exceptionContext != null);
if (_exceptionContext.Exception != null)
if (_exceptionContext.Exception != null && !_exceptionContext.ExceptionHandled)
{
_diagnosticSource.BeforeOnException(_exceptionContext, current.Filter);

Expand All @@ -445,7 +444,7 @@ private async Task InvokeExceptionFilterAsync()

_diagnosticSource.AfterOnException(_exceptionContext, current.Filter);

if (_exceptionContext.Exception == null)
if (_exceptionContext.Exception == null || _exceptionContext.ExceptionHandled)
{
_logger.ExceptionFilterShortCircuited(current.Filter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public async Task InvokeAction_InvokesAsyncExceptionFilter_WhenActionThrows()
}

[Fact]
public async Task InvokeAction_InvokesExceptionFilter_ShortCircuit()
public async Task InvokeAction_InvokesExceptionFilter_ShortCircuit_ExceptionNull()
{
// Arrange
var filter1 = new Mock<IExceptionFilter>(MockBehavior.Strict);
Expand All @@ -171,12 +171,38 @@ public async Task InvokeAction_InvokesExceptionFilter_ShortCircuit()
}

[Fact]
public async Task InvokeAction_InvokesAsyncExceptionFilter_ShortCircuit()
public async Task InvokeAction_InvokesExceptionFilter_ShortCircuit_ExceptionHandled()
{
// Arrange
var filter1 = new Mock<IExceptionFilter>(MockBehavior.Strict);

var filter2 = new Mock<IExceptionFilter>(MockBehavior.Strict);
filter2
.Setup(f => f.OnException(It.IsAny<ExceptionContext>()))
.Callback<ExceptionContext>(context =>
{
context.ExceptionHandled = true;
})
.Verifiable();

var invoker = CreateInvoker(new[] { filter1.Object, filter2.Object }, actionThrows: true);

// Act
await invoker.InvokeAsync();

// Assert
filter2.Verify(
f => f.OnException(It.IsAny<ExceptionContext>()),
Times.Once());
}

[Fact]
public async Task InvokeAction_InvokesAsyncExceptionFilter_ShortCircuit_ExceptionNull()
{
// Arrange
var filter1 = new Mock<IExceptionFilter>(MockBehavior.Strict);
var filter2 = new Mock<IAsyncExceptionFilter>(MockBehavior.Strict);

filter2
.Setup(f => f.OnExceptionAsync(It.IsAny<ExceptionContext>()))
.Callback<ExceptionContext>(context =>
Expand All @@ -187,6 +213,34 @@ public async Task InvokeAction_InvokesAsyncExceptionFilter_ShortCircuit()
.Returns<ExceptionContext>((context) => Task.FromResult(true))
.Verifiable();

var filterMetadata = new IFilterMetadata[] { filter1.Object, filter2.Object };
var invoker = CreateInvoker(filterMetadata, actionThrows: true);

// Act
await invoker.InvokeAsync();

// Assert
filter2.Verify(
f => f.OnExceptionAsync(It.IsAny<ExceptionContext>()),
Times.Once());
}

[Fact]
public async Task InvokeAction_InvokesAsyncExceptionFilter_ShortCircuit_ExceptionHandled()
{
// Arrange
var filter1 = new Mock<IExceptionFilter>(MockBehavior.Strict);

var filter2 = new Mock<IAsyncExceptionFilter>(MockBehavior.Strict);
filter2
.Setup(f => f.OnExceptionAsync(It.IsAny<ExceptionContext>()))
.Callback<ExceptionContext>(context =>
{
context.ExceptionHandled = true;
})
.Returns<ExceptionContext>((context) => Task.FromResult(true))
.Verifiable();

var invoker = CreateInvoker(new IFilterMetadata[] { filter1.Object, filter2.Object }, actionThrows: true);

// Act
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class ShortCircuitExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
context.Exception = null;
context.ExceptionHandled = true;
}
}
}

0 comments on commit 27bde12

Please sign in to comment.