Move CallsHandler property to ExceptionContextCatchBlock.

Whether or not an exception can be handled depends of the catch block
code, so the CallsHandler properly belongs on the catch block class
rather than varying per context on the exception logger context class.
This commit is contained in:
davidmatson 2013-11-06 13:12:01 -08:00
Родитель 7cdde3363d
Коммит 865c16c32e
32 изменённых файлов: 136 добавлений и 142 удалений

Просмотреть файл

@ -337,8 +337,7 @@ namespace System.Web.Http.Owin
ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo.SourceException,
OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferContent, request, response);
await _exceptionLogger.LogAsync(exceptionContext, canBeHandled: true,
cancellationToken: cancellationToken);
await _exceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpResponseMessage errorResponse = await _exceptionHandler.HandleAsync(exceptionContext,
cancellationToken);
@ -373,8 +372,7 @@ namespace System.Web.Http.Owin
ExceptionContext errorExceptionContext = new ExceptionContext(errorException,
OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferError, request, response);
await _exceptionLogger.LogAsync(errorExceptionContext, canBeHandled: false,
cancellationToken: cancellationToken);
await _exceptionLogger.LogAsync(errorExceptionContext, cancellationToken);
response.Dispose();
return request.CreateResponse(HttpStatusCode.InternalServerError);
@ -463,8 +461,7 @@ namespace System.Web.Http.Owin
// status code and headers across the wire. Log the exception, but then just abort.
ExceptionContext exceptionContext = new ExceptionContext(exception,
OwinExceptionCatchBlocks.HttpMessageHandlerAdapterStreamContent, request, response);
await _exceptionLogger.LogAsync(exceptionContext, canBeHandled: false,
cancellationToken: cancellationToken);
await _exceptionLogger.LogAsync(exceptionContext, cancellationToken);
AbortResponseStream(body);
}

Просмотреть файл

@ -9,12 +9,13 @@ namespace System.Web.Http.Owin
{
private static readonly ExceptionContextCatchBlock _httpMessageHandlerAdapterBufferContent =
new ExceptionContextCatchBlock(typeof(HttpMessageHandlerAdapter).Name + ".BufferContent",
isTopLevel: true);
isTopLevel: true, callsHandler: true);
private static readonly ExceptionContextCatchBlock _httpMessageHandlerAdapterBufferError =
new ExceptionContextCatchBlock(typeof(HttpMessageHandlerAdapter).Name + ".BufferError", isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpMessageHandlerAdapter).Name + ".BufferError", isTopLevel: true,
callsHandler: false);
private static readonly ExceptionContextCatchBlock _httpMessageHandlerAdapterStreamContent =
new ExceptionContextCatchBlock(typeof(HttpMessageHandlerAdapter).Name + ".StreamContent",
isTopLevel: true);
isTopLevel: true, callsHandler: false);
/// <summary>Gets the catch block in <see cref="HttpMessageHandlerAdapter"/>.BufferContent.</summary>
public static ExceptionContextCatchBlock HttpMessageHandlerAdapterBufferContent

Просмотреть файл

@ -355,8 +355,7 @@ namespace System.Web.Http.WebHost
ExceptionContextCatchBlock catchBlock = WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent;
ExceptionContext exceptionContext = new ExceptionContext(exception, catchBlock, request, response);
await exceptionLogger.LogAsync(exceptionContext, canBeHandled: false,
cancellationToken: cancellationToken);
await exceptionLogger.LogAsync(exceptionContext, cancellationToken);
// Streamed content may have been written and cannot be recalled.
// Our only choice is to abort the connection.
@ -461,6 +460,8 @@ namespace System.Web.Http.WebHost
Contract.Assert(httpContextBase.Response != null);
Contract.Assert(request != null);
Contract.Assert(exception != null);
Contract.Assert(catchBlock != null);
Contract.Assert(catchBlock.CallsHandler);
HttpResponseBase httpResponseBase = httpContextBase.Response;
HttpResponseMessage errorResponse = null;
@ -481,8 +482,7 @@ namespace System.Web.Http.WebHost
{
Response = response
};
await exceptionLogger.LogAsync(exceptionContext, canBeHandled: true,
cancellationToken: cancellationToken);
await exceptionLogger.LogAsync(exceptionContext, cancellationToken);
errorResponse = await exceptionHandler.HandleAsync(exceptionContext, cancellationToken);
if (errorResponse == null)
@ -541,8 +541,7 @@ namespace System.Web.Http.WebHost
ExceptionContext exceptionContext = new ExceptionContext(exception,
WebHostExceptionCatchBlocks.HttpControllerHandlerBufferError, request, errorResponse);
await exceptionLogger.LogAsync(exceptionContext, canBeHandled: false,
cancellationToken: cancellationToken);
await exceptionLogger.LogAsync(exceptionContext, cancellationToken);
// Failure writing the error response. Likely cause is a formatter
// serialization exception. Create empty error response and

Просмотреть файл

@ -9,13 +9,16 @@ namespace System.Web.Http.WebHost
public static class WebHostExceptionCatchBlocks
{
private static readonly ExceptionContextCatchBlock _httpControllerHandlerBufferContent =
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".BufferContent", isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".BufferContent", isTopLevel: true,
callsHandler: true);
private static readonly ExceptionContextCatchBlock _httpControllerHandlerBufferError =
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".BufferError", isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".BufferError", isTopLevel: true,
callsHandler: false);
private static readonly ExceptionContextCatchBlock _httpControllerHandlerStreamContent =
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".StreamContent", isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpControllerHandler).Name + ".StreamContent", isTopLevel: true,
callsHandler: false);
private static readonly ExceptionContextCatchBlock _httpWebRoute =
new ExceptionContextCatchBlock(typeof(HttpWebRoute).Name, isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpWebRoute).Name, isTopLevel: true, callsHandler: true);
/// <summary>
/// Gets the label for the catch block in

Просмотреть файл

@ -101,7 +101,7 @@ namespace System.Web.Http.Batch
ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo.SourceException,
ExceptionCatchBlocks.HttpBatchHandler, request);
await ExceptionLogger.LogAsync(exceptionContext, canBeHandled: true, cancellationToken: cancellationToken);
await ExceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpResponseMessage response = await ExceptionHandler.HandleAsync(exceptionContext, cancellationToken);
if (response == null)

Просмотреть файл

@ -56,8 +56,7 @@ namespace System.Web.Http.Controllers
ExceptionContext exceptionContext = new ExceptionContext(exception, ExceptionCatchBlocks.IExceptionFilter,
_context);
await _exceptionLogger.LogAsync(exceptionContext, canBeHandled: true,
cancellationToken: cancellationToken);
await _exceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpActionExecutedContext executedContext = new HttpActionExecutedContext(_context, exception);

Просмотреть файл

@ -124,8 +124,7 @@ namespace System.Web.Http.Dispatcher
ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo.SourceException,
ExceptionCatchBlocks.HttpControllerDispatcher, request);
await ExceptionLogger.LogAsync(exceptionContext, canBeHandled: true,
cancellationToken: cancellationToken);
await ExceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpResponseMessage response = await ExceptionHandler.HandleAsync(exceptionContext, cancellationToken);
if (response == null)

Просмотреть файл

@ -10,13 +10,13 @@ namespace System.Web.Http.ExceptionHandling
public static class ExceptionCatchBlocks
{
private static readonly ExceptionContextCatchBlock _httpBatchHandler =
new ExceptionContextCatchBlock(typeof(HttpBatchHandler).Name, isTopLevel: false);
new ExceptionContextCatchBlock(typeof(HttpBatchHandler).Name, isTopLevel: false, callsHandler: true);
private static readonly ExceptionContextCatchBlock _httpControllerDispatcher =
new ExceptionContextCatchBlock(typeof(HttpControllerDispatcher).Name, isTopLevel: false);
new ExceptionContextCatchBlock(typeof(HttpControllerDispatcher).Name, isTopLevel: false, callsHandler: true);
private static readonly ExceptionContextCatchBlock _httpServer =
new ExceptionContextCatchBlock(typeof(HttpServer).Name, isTopLevel: true);
new ExceptionContextCatchBlock(typeof(HttpServer).Name, isTopLevel: true, callsHandler: true);
private static readonly ExceptionContextCatchBlock _exceptionFilter =
new ExceptionContextCatchBlock(typeof(IExceptionFilter).Name, isTopLevel: false);
new ExceptionContextCatchBlock(typeof(IExceptionFilter).Name, isTopLevel: false, callsHandler: true);
/// <summary>Gets the catch block in <see cref="HttpBatchHandler"/>.SendAsync.</summary>
public static ExceptionContextCatchBlock HttpBatchHandler

Просмотреть файл

@ -10,6 +10,7 @@ namespace System.Web.Http.ExceptionHandling
{
private readonly string _name;
private readonly bool _isTopLevel;
private readonly bool _callsHandler;
/// <summary>
/// Initializes a new instance of <see cref="ExceptionContextCatchBlock"/> with the values provided.
@ -18,12 +19,15 @@ namespace System.Web.Http.ExceptionHandling
/// <param name="isTopLevel">
/// A value indicating whether the catch block where the exception was caught is the last one before the host.
/// </param>
/// <param name="callsHandler">
/// A value indicating whether exceptions in the catch block can be handled after they are logged.
/// </param>
/// <remarks>
/// To compare an exception catch block with a well-known value, see classes like
/// <see cref="ExceptionCatchBlocks"/> for the specific objects to use.
/// This constructor is only intended for use within static classes that define such well-known catch blocks.
/// </remarks>
public ExceptionContextCatchBlock(string name, bool isTopLevel)
public ExceptionContextCatchBlock(string name, bool isTopLevel, bool callsHandler)
{
if (name == null)
{
@ -32,6 +36,7 @@ namespace System.Web.Http.ExceptionHandling
_name = name;
_isTopLevel = isTopLevel;
_callsHandler = callsHandler;
}
/// <summary>Gets a label for the catch block in which the exception was caught.</summary>
@ -49,6 +54,27 @@ namespace System.Web.Http.ExceptionHandling
get { return _isTopLevel; }
}
/// <summary>
/// Gets a value indicating whether exceptions in the catch block can be handled after they are logged.
/// </summary>
/// <remarks>
/// <para>
/// Some exceptions are caught after a response is already partially sent, which prevents sending a new
/// response to handle the exception. In such cases, <see cref="IExceptionLogger"/> will be called to log the
/// exception, but the <see cref="IExceptionHandler"/> will not be called.
/// </para>
/// <para>
/// If this value is <see langword="true"/>, exceptions from this catch block will be provided to both
/// <see cref="IExceptionLogger"/> and <see cref="IExceptionHandler"/>. If this value is
/// see langword="false"/>, exceptions from this catch block cannot be handled and will only be provided to
/// <see cref="IExceptionLogger"/>.
/// </para>
/// </remarks>
public bool CallsHandler
{
get { return _callsHandler; }
}
/// <inheritdoc/>
public override string ToString()
{

Просмотреть файл

@ -6,14 +6,12 @@ namespace System.Web.Http.ExceptionHandling
public class ExceptionLoggerContext
{
private readonly ExceptionContext _exceptionContext;
private readonly bool _canBeHandled;
/// <summary>
/// Initializes a new instance of the <see cref="ExceptionLoggerContext"/> class using the values provided.
/// </summary>
/// <param name="exceptionContext">The exception context.</param>
/// <param name="canBeHandled">A value indicating whether the exception can subsequently be handled.</param>
public ExceptionLoggerContext(ExceptionContext exceptionContext, bool canBeHandled)
public ExceptionLoggerContext(ExceptionContext exceptionContext)
{
if (exceptionContext == null)
{
@ -21,7 +19,6 @@ namespace System.Web.Http.ExceptionHandling
}
_exceptionContext = exceptionContext;
_canBeHandled = canBeHandled;
}
/// <summary>Gets or sets the exception context providing the exception and related data.</summary>
@ -29,19 +26,5 @@ namespace System.Web.Http.ExceptionHandling
{
get { return _exceptionContext; }
}
/// <summary>
/// Gets or sets a value indicating whether the exception can subsequently be handled by an
/// <see cref="IExceptionHandler"/> to produce a new response message.
/// </summary>
/// <remarks>
/// Some exceptions are caught after a response is already partially sent, which prevents sending a new
/// response to handle the exception. In such cases, <see cref="IExceptionLogger"/> will be called to log the
/// exception, but the <see cref="IExceptionHandler"/> will not be called.
/// </remarks>
public bool CanBeHandled
{
get { return _canBeHandled; }
}
}
}

Просмотреть файл

@ -11,10 +11,9 @@ namespace System.Web.Http.ExceptionHandling
/// <summary>Calls an exception logger.</summary>
/// <param name="logger">The unhandled exception logger.</param>
/// <param name="context">The exception context.</param>
/// <param name="canBeHandled">A value indicating whether the exception can subsequently be handled.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>A task representing the asynchronous exception logging operation.</returns>
public static Task LogAsync(this IExceptionLogger logger, ExceptionContext context, bool canBeHandled,
public static Task LogAsync(this IExceptionLogger logger, ExceptionContext context,
CancellationToken cancellationToken)
{
if (logger == null)
@ -27,7 +26,7 @@ namespace System.Web.Http.ExceptionHandling
throw new ArgumentNullException("context");
}
ExceptionLoggerContext loggerContext = new ExceptionLoggerContext(context, canBeHandled);
ExceptionLoggerContext loggerContext = new ExceptionLoggerContext(context);
return logger.LogAsync(loggerContext, cancellationToken);
}
}

Просмотреть файл

@ -235,8 +235,7 @@ namespace System.Web.Http
ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo.SourceException,
ExceptionCatchBlocks.HttpServer, request);
await ExceptionLogger.LogAsync(exceptionContext, canBeHandled: true,
cancellationToken: cancellationToken);
await ExceptionLogger.LogAsync(exceptionContext, cancellationToken);
HttpResponseMessage response = await ExceptionHandler.HandleAsync(exceptionContext,
cancellationToken);

Просмотреть файл

@ -28,7 +28,7 @@ namespace System.Web.Http.Owin.ExceptionHandling
private static ExceptionLoggerContext CreateContext()
{
return new ExceptionLoggerContext(new ExceptionContext(), canBeHandled: false);
return new ExceptionLoggerContext(new ExceptionContext());
}
private static EmptyExceptionLogger CreateProductUnderTest()

Просмотреть файл

@ -849,10 +849,8 @@ namespace System.Web.Http.Owin
&& c.Response == expectedResponse;
exceptionLoggerMock.Verify(l => l.LogAsync(
It.Is<ExceptionLoggerContext>(c => c.CanBeHandled == true
&& exceptionContextMatches(c.ExceptionContext)),
It.Is<ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)),
expectedCancellationToken), Times.Once());
exceptionHandlerMock.Verify(h => h.HandleAsync(
It.Is<ExceptionHandlerContext>((c) => exceptionContextMatches(c.ExceptionContext)),
expectedCancellationToken), Times.Once());
@ -1082,8 +1080,7 @@ namespace System.Web.Http.Owin
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == true
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedOriginalException
&& c.ExceptionContext.CatchBlock ==
OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferContent
@ -1091,8 +1088,7 @@ namespace System.Web.Http.Owin
&& c.ExceptionContext.Response == expectedOriginalResponse),
expectedCancellationToken), Times.Once());
mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == false
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedErrorException
&& c.ExceptionContext.CatchBlock ==
OwinExceptionCatchBlocks.HttpMessageHandlerAdapterBufferError
@ -1221,7 +1217,6 @@ namespace System.Web.Http.Owin
mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>((c) =>
c != null
&& c.CanBeHandled == false
&& c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedException
&& c.ExceptionContext.CatchBlock ==

Просмотреть файл

@ -20,7 +20,8 @@ namespace System.Web.Http.Owin
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.BufferContent", isTopLevel: true);
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.BufferContent", isTopLevel: true,
callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -45,7 +46,8 @@ namespace System.Web.Http.Owin
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.BufferError", isTopLevel: true);
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.BufferError", isTopLevel: true,
callsHandler: false);
AssertEqual(expected, catchBlock);
}
@ -70,7 +72,8 @@ namespace System.Web.Http.Owin
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.StreamContent", isTopLevel: true);
new ExceptionContextCatchBlock("HttpMessageHandlerAdapter.StreamContent", isTopLevel: true,
callsHandler: false);
AssertEqual(expected, catchBlock);
}
@ -98,6 +101,7 @@ namespace System.Web.Http.Owin
Assert.NotNull(actual);
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.IsTopLevel, actual.IsTopLevel);
Assert.Equal(expected.CallsHandler, actual.CallsHandler);
}
}
}

Просмотреть файл

@ -205,7 +205,7 @@ namespace System.Web.Http.Owin
ExceptionLoggerContext context = new ExceptionLoggerContext(new ExceptionContext()
{
Exception = new Exception()
}, canBeHandled: false);
});
CancellationToken cancellationToken = CancellationToken.None;
expected

Просмотреть файл

@ -194,8 +194,7 @@ namespace System.Web.Http
&& c.Request == expectedRequest;
exceptionLoggerMock.Verify(l => l.LogAsync(
It.Is<ExceptionLoggerContext>(c => c.CanBeHandled == true
&& exceptionContextMatches(c.ExceptionContext)),
It.Is<ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)),
cancellationToken), Times.Once());
exceptionHandlerMock.Verify(h => h.HandleAsync(

Просмотреть файл

@ -149,8 +149,7 @@ namespace System.Web.Http.Controllers
&& c.ActionContext == expectedActionContext;
exceptionLoggerMock.Verify(l => l.LogAsync(
It.Is<ExceptionLoggerContext>(c => c.CanBeHandled == true
&& exceptionContextMatches(c.ExceptionContext)),
It.Is<ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)),
cancellationToken), Times.Once());
}
}

Просмотреть файл

@ -228,8 +228,7 @@ namespace System.Web.Http.Dispatcher
&& c.Request == expectedRequest;
exceptionLoggerMock.Verify(l => l.LogAsync(
It.Is<ExceptionLoggerContext>(c => c.CanBeHandled == true
&& exceptionContextMatches(c.ExceptionContext)),
It.Is<ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)),
cancellationToken), Times.Once());
exceptionHandlerMock.Verify(h => h.HandleAsync(

Просмотреть файл

@ -132,7 +132,7 @@ namespace System.Web.Http.ExceptionHandling
private static ExceptionLoggerContext CreateContext()
{
return new ExceptionLoggerContext(new ExceptionContext(), canBeHandled: true);
return new ExceptionLoggerContext(new ExceptionContext());
}
private static IExceptionLogger CreateDummyLogger()

Просмотреть файл

@ -14,7 +14,7 @@ namespace System.Web.Http.ExceptionHandling
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpBatchHandler", isTopLevel: false);
new ExceptionContextCatchBlock("HttpBatchHandler", isTopLevel: false, callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -39,7 +39,7 @@ namespace System.Web.Http.ExceptionHandling
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpControllerDispatcher", isTopLevel: false);
new ExceptionContextCatchBlock("HttpControllerDispatcher", isTopLevel: false, callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -64,7 +64,7 @@ namespace System.Web.Http.ExceptionHandling
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpServer", isTopLevel: true);
new ExceptionContextCatchBlock("HttpServer", isTopLevel: true, callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -89,7 +89,7 @@ namespace System.Web.Http.ExceptionHandling
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("IExceptionFilter", isTopLevel: false);
new ExceptionContextCatchBlock("IExceptionFilter", isTopLevel: false, callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -117,6 +117,7 @@ namespace System.Web.Http.ExceptionHandling
Assert.NotNull(actual);
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.IsTopLevel, actual.IsTopLevel);
Assert.Equal(expected.CallsHandler, actual.CallsHandler);
}
}
}

Просмотреть файл

@ -13,9 +13,10 @@ namespace System.Web.Http.ExceptionHandling
// Arrange
string name = null;
bool isTopLevel = false;
bool callsHandler = false;
// Act & Assert
Assert.ThrowsArgumentNull(() => CreateProductUnderTest(name, isTopLevel), "name");
Assert.ThrowsArgumentNull(() => CreateProductUnderTest(name, isTopLevel, callsHandler), "name");
}
[Fact]
@ -24,7 +25,8 @@ namespace System.Web.Http.ExceptionHandling
// Arrange
string expectedName = "TheName";
bool isTopLevel = true;
ExceptionContextCatchBlock product = CreateProductUnderTest(expectedName, isTopLevel);
bool callsHandler = false;
ExceptionContextCatchBlock product = CreateProductUnderTest(expectedName, isTopLevel, callsHandler);
// Act
string name = product.Name;
@ -40,7 +42,8 @@ namespace System.Web.Http.ExceptionHandling
{
// Arrange
string name = "IgnoreName";
ExceptionContextCatchBlock product = CreateProductUnderTest(name, expectedIsTopLevel);
bool callsHandler = false;
ExceptionContextCatchBlock product = CreateProductUnderTest(name, expectedIsTopLevel, callsHandler);
// Act
bool isTopLevel = product.IsTopLevel;
@ -49,13 +52,31 @@ namespace System.Web.Http.ExceptionHandling
Assert.Equal(expectedIsTopLevel, isTopLevel);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void CallsHandler_IsSpecifiedValue(bool expectedCallsHandler)
{
// Arrange
string name = "IgnoreName";
bool isTopLevel = true;
ExceptionContextCatchBlock product = CreateProductUnderTest(name, isTopLevel, expectedCallsHandler);
// Act
bool callsHandler = product.CallsHandler;
// Assert
Assert.Equal(expectedCallsHandler, callsHandler);
}
[Fact]
public void ToString_ReturnsName()
{
// Arrange
string expectedName = "TheName";
bool isTopLevel = false;
object product = CreateProductUnderTest(expectedName, isTopLevel);
bool callsHandler= false;
object product = CreateProductUnderTest(expectedName, isTopLevel, callsHandler);
// Act
string value = product.ToString();
@ -77,9 +98,9 @@ namespace System.Web.Http.ExceptionHandling
Assert.Equal("Name: {Name}, IsTopLevel: {IsTopLevel}", value);
}
private static ExceptionContextCatchBlock CreateProductUnderTest(string name, bool isTopLevel)
private static ExceptionContextCatchBlock CreateProductUnderTest(string name, bool isTopLevel, bool callsHandler)
{
return new ExceptionContextCatchBlock(name, isTopLevel);
return new ExceptionContextCatchBlock(name, isTopLevel, callsHandler);
}
}
}

Просмотреть файл

@ -472,7 +472,7 @@ namespace System.Web.Http.ExceptionHandling
private static ExceptionContextCatchBlock CreateCatchBlock()
{
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: false);
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: false, callsHandler: false);
}
private static HttpControllerContext CreateControllerContext()

Просмотреть файл

@ -171,7 +171,7 @@ namespace System.Web.Http.ExceptionHandling
ExceptionHandlerContext context = CreateContext(new ExceptionContext
{
CatchBlock = new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevelCatchBlock)
CatchBlock = new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevelCatchBlock, callsHandler: false)
});
// Act

Просмотреть файл

@ -11,10 +11,9 @@ namespace System.Web.Http.ExceptionHandling
{
// Arrange
ExceptionContext context = null;
bool canBeHandled = true;
// Act & Assert
Assert.ThrowsArgumentNull(() => CreateProductUnderTest(context, canBeHandled), "exceptionContext");
Assert.ThrowsArgumentNull(() => CreateProductUnderTest(context), "exceptionContext");
}
[Fact]
@ -22,8 +21,7 @@ namespace System.Web.Http.ExceptionHandling
{
// Arrange
ExceptionContext expectedContext = CreateContext();
bool canBeHandled = false;
ExceptionLoggerContext product = CreateProductUnderTest(expectedContext, canBeHandled);
ExceptionLoggerContext product = CreateProductUnderTest(expectedContext);
// Act
ExceptionContext context = product.ExceptionContext;
@ -32,31 +30,14 @@ namespace System.Web.Http.ExceptionHandling
Assert.Same(expectedContext, context);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void CanBeHandledGet_ReturnsSpecifiedValue(bool expectedCanBeHandled)
{
// Arrange
ExceptionContext context = CreateContext();
ExceptionLoggerContext product = CreateProductUnderTest(context, expectedCanBeHandled);
// Act
bool canBeHandled = product.CanBeHandled;
// Assert
Assert.Equal(expectedCanBeHandled, canBeHandled);
}
private static ExceptionContext CreateContext()
{
return new ExceptionContext();
}
private static ExceptionLoggerContext CreateProductUnderTest(ExceptionContext exceptionContext,
bool canBeHandled)
private static ExceptionLoggerContext CreateProductUnderTest(ExceptionContext exceptionContext)
{
return new ExceptionLoggerContext(exceptionContext, canBeHandled);
return new ExceptionLoggerContext(exceptionContext);
}
}
}

Просмотреть файл

@ -9,10 +9,8 @@ namespace System.Web.Http.ExceptionHandling
{
public class ExceptionLoggerExtensionsTests
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public void LogAsync_DelegatesToInterfaceLogAsync(bool expectedCanBeHandled)
[Fact]
public void LogAsync_DelegatesToInterfaceLogAsync()
{
// Arrange
Task expectedTask = CreateCompletedTask();
@ -29,15 +27,13 @@ namespace System.Web.Http.ExceptionHandling
CancellationToken expectedCancellationToken = tokenSource.Token;
// Act
Task task = ExceptionLoggerExtensions.LogAsync(logger, expectedContext, expectedCanBeHandled,
expectedCancellationToken);
Task task = ExceptionLoggerExtensions.LogAsync(logger, expectedContext, expectedCancellationToken);
// Assert
Assert.Same(expectedTask, task);
task.WaitUntilCompleted();
mock.Verify(h => h.LogAsync(It.Is<ExceptionLoggerContext>(
c => c.ExceptionContext == expectedContext && c.CanBeHandled == expectedCanBeHandled),
mock.Verify(h => h.LogAsync(It.Is<ExceptionLoggerContext>(c => c.ExceptionContext == expectedContext),
expectedCancellationToken), Times.Once());
}
}
@ -48,12 +44,11 @@ namespace System.Web.Http.ExceptionHandling
// Arrange
IExceptionLogger logger = null;
ExceptionContext context = CreateContext();
bool canBeHandled = true;
CancellationToken cancellationToken = CancellationToken.None;
// Act & Assert
Assert.ThrowsArgumentNull(() =>
ExceptionLoggerExtensions.LogAsync(logger, context, canBeHandled, cancellationToken), "logger");
ExceptionLoggerExtensions.LogAsync(logger, context, cancellationToken), "logger");
}
[Fact]
@ -62,12 +57,11 @@ namespace System.Web.Http.ExceptionHandling
// Arrange
IExceptionLogger logger = CreateDummyLogger();
ExceptionContext context = null;
bool canBeHandled = true;
CancellationToken cancellationToken = CancellationToken.None;
// Act & Assert
Assert.ThrowsArgumentNull(() =>
ExceptionLoggerExtensions.LogAsync(logger, context, canBeHandled, cancellationToken), "context");
ExceptionLoggerExtensions.LogAsync(logger, context, cancellationToken), "context");
}
private static CancellationTokenSource CreateCancellationTokenSource()

Просмотреть файл

@ -316,7 +316,7 @@ namespace System.Web.Http.ExceptionHandling
private static ExceptionLoggerContext CreateContext(ExceptionContext exceptionContext)
{
return new ExceptionLoggerContext(exceptionContext, canBeHandled: false);
return new ExceptionLoggerContext(exceptionContext);
}
private static Exception CreateException(IDictionary data)

Просмотреть файл

@ -392,7 +392,7 @@ namespace System.Web.Http.ExceptionHandling
private static ExceptionContextCatchBlock CreateNonTopLevelCatchBlock()
{
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: false);
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: false, callsHandler: false);
}
private static LastChanceExceptionHandler CreateProductUnderTest(IExceptionHandler innerHandler)
@ -407,7 +407,7 @@ namespace System.Web.Http.ExceptionHandling
private static ExceptionContextCatchBlock CreateTopLevelCatchBlock()
{
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: true);
return new ExceptionContextCatchBlock("IgnoreCaughtAt", isTopLevel: true, callsHandler: false);
}
}
}

Просмотреть файл

@ -418,8 +418,7 @@ namespace System.Web.Http
&& c.Request == expectedRequest;
exceptionLoggerMock.Verify(l => l.LogAsync(
It.Is<ExceptionLoggerContext>(c => c.CanBeHandled == true
&& exceptionContextMatches(c.ExceptionContext)),
It.Is<ExceptionLoggerContext>(c => exceptionContextMatches(c.ExceptionContext)),
cancellationToken), Times.Once());
exceptionHandlerMock.Verify(h => h.HandleAsync(

Просмотреть файл

@ -933,8 +933,7 @@ namespace System.Web.Http.WebHost
task.WaitUntilCompleted();
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
mock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == false
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedException
&& c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerStreamContent
&& c.ExceptionContext.Request == expectedRequest
@ -982,8 +981,7 @@ namespace System.Web.Http.WebHost
&& c.Response == expectedResponse;
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == true && exceptionContextMatches(c.ExceptionContext)),
expectedCancellationToken), Times.Once());
exceptionContextMatches(c.ExceptionContext)), expectedCancellationToken), Times.Once());
handlerMock.Verify(l => l.HandleAsync(It.Is<ExceptionHandlerContext>(c =>
exceptionContextMatches(c.ExceptionContext)), expectedCancellationToken), Times.Once());
}
@ -1110,16 +1108,14 @@ namespace System.Web.Http.WebHost
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == true
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedOriginalException
&& c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerBufferContent
&& c.ExceptionContext.Request == expectedRequest
&& c.ExceptionContext.Response == expectedOriginalResponse),
expectedCancellationToken), Times.Once());
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == false
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedErrorException
&& c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerBufferError
&& c.ExceptionContext.Request == expectedRequest

Просмотреть файл

@ -181,8 +181,7 @@ namespace System.Web.Http.WebHost.Routing
&& c.Request == expectedRequest;
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == true && exceptionContextMatches(c.ExceptionContext)),
CancellationToken.None), Times.Once());
exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once());
handlerMock.Verify(l => l.HandleAsync(It.Is<ExceptionHandlerContext>(c =>
exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once());
}
@ -309,15 +308,13 @@ namespace System.Web.Http.WebHost.Routing
Assert.Equal(TaskStatus.RanToCompletion, task.Status);
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == true
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedOriginalException
&& c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute
&& c.ExceptionContext.Request == expectedRequest),
CancellationToken.None), Times.Once());
loggerMock.Verify(l => l.LogAsync(It.Is<ExceptionLoggerContext>(c =>
c.CanBeHandled == false
&& c.ExceptionContext != null
c.ExceptionContext != null
&& c.ExceptionContext.Exception == expectedErrorException
&& c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerBufferError
&& c.ExceptionContext.Request == expectedRequest

Просмотреть файл

@ -15,7 +15,8 @@ namespace System.Web.Http.WebHost
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpControllerHandler.BufferContent", isTopLevel: true);
new ExceptionContextCatchBlock("HttpControllerHandler.BufferContent", isTopLevel: true,
callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -40,7 +41,8 @@ namespace System.Web.Http.WebHost
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpControllerHandler.BufferError", isTopLevel: true);
new ExceptionContextCatchBlock("HttpControllerHandler.BufferError", isTopLevel: true,
callsHandler: false);
AssertEqual(expected, catchBlock);
}
@ -65,7 +67,8 @@ namespace System.Web.Http.WebHost
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpControllerHandler.StreamContent", isTopLevel: true);
new ExceptionContextCatchBlock("HttpControllerHandler.StreamContent", isTopLevel: true,
callsHandler: false);
AssertEqual(expected, catchBlock);
}
@ -90,7 +93,7 @@ namespace System.Web.Http.WebHost
// Assert
ExceptionContextCatchBlock expected =
new ExceptionContextCatchBlock("HttpWebRoute", isTopLevel: true);
new ExceptionContextCatchBlock("HttpWebRoute", isTopLevel: true, callsHandler: true);
AssertEqual(expected, catchBlock);
}
@ -118,6 +121,7 @@ namespace System.Web.Http.WebHost
Assert.NotNull(actual);
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.IsTopLevel, actual.IsTopLevel);
Assert.Equal(expected.CallsHandler, actual.CallsHandler);
}
}
}