Make TestServer handle exceptions from OnStarting #1594
This commit is contained in:
parent
cfe9b26a34
commit
f6cda4fab7
|
|
@ -109,7 +109,16 @@ namespace Microsoft.AspNetCore.TestHost
|
||||||
if (!_responseFeature.HasStarted)
|
if (!_responseFeature.HasStarted)
|
||||||
{
|
{
|
||||||
// Sets 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.
|
// Copy the feature collection so we're not multi-threading on the same collection.
|
||||||
var newFeatures = new FeatureCollection();
|
var newFeatures = new FeatureCollection();
|
||||||
foreach (var pair in _httpContext.Features)
|
foreach (var pair in _httpContext.Features)
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,63 @@ namespace Microsoft.AspNetCore.TestHost
|
||||||
Assert.IsType<InvalidOperationException>(ex.GetBaseException());
|
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>
|
private class DummyApplication : IHttpApplication<Context>
|
||||||
{
|
{
|
||||||
RequestDelegate _application;
|
RequestDelegate _application;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue