Make TestServer handle exceptions from OnStarting #1594

This commit is contained in:
Chris Ross (ASP.NET) 2018-11-16 16:39:50 -08:00
parent cfe9b26a34
commit f6cda4fab7
2 changed files with 67 additions and 1 deletions

View File

@ -109,7 +109,16 @@ namespace Microsoft.AspNetCore.TestHost
if (!_responseFeature.HasStarted)
{
// Sets HasStarted
await _responseFeature.FireOnSendingHeadersAsync();
try
{
await _responseFeature.FireOnSendingHeadersAsync();
}
catch (Exception ex)
{
Abort(ex);
return;
}
// Copy the feature collection so we're not multi-threading on the same collection.
var newFeatures = new FeatureCollection();
foreach (var pair in _httpContext.Features)

View File

@ -272,6 +272,63 @@ namespace Microsoft.AspNetCore.TestHost
Assert.IsType<InvalidOperationException>(ex.GetBaseException());
}
[Fact]
public Task ExceptionFromOnStartingFirstWriteIsReported()
{
var handler = new ClientHandler(PathString.Empty, new DummyApplication(context =>
{
context.Response.OnStarting(() =>
{
throw new InvalidOperationException(new string('a', 1024 * 32));
});
return context.Response.WriteAsync("Hello World");
}));
var httpClient = new HttpClient(handler);
return Assert.ThrowsAsync<InvalidOperationException>(() => httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead));
}
[Fact]
public Task ExceptionFromOnStartingWithNoWriteIsReported()
{
var handler = new ClientHandler(PathString.Empty, new DummyApplication(context =>
{
context.Response.OnStarting(() =>
{
throw new InvalidOperationException(new string('a', 1024 * 32));
});
return Task.CompletedTask;
}));
var httpClient = new HttpClient(handler);
return Assert.ThrowsAsync<InvalidOperationException>(() => httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead));
}
[Fact]
public Task ExceptionFromOnStartingWithErrorHandlerIsReported()
{
var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context =>
{
context.Response.OnStarting(() =>
{
throw new InvalidOperationException(new string('a', 1024 * 32));
});
try
{
await context.Response.WriteAsync("Hello World");
}
catch (Exception ex)
{
// This is no longer the first write, so it doesn't trigger OnStarting again.
// The exception is large enough that it fills the pipe and stalls.
await context.Response.WriteAsync(ex.ToString());
}
}));
var httpClient = new HttpClient(handler);
return Assert.ThrowsAsync<InvalidOperationException>(() => httpClient.GetAsync("https://example.com/",
HttpCompletionOption.ResponseHeadersRead));
}
private class DummyApplication : IHttpApplication<Context>
{
RequestDelegate _application;