#82 - Improve error handling mechanics.
This commit is contained in:
parent
8b7d33baaf
commit
fec32f6746
|
|
@ -60,6 +60,8 @@ namespace Microsoft.AspNet.Security.Infrastructure
|
||||||
|
|
||||||
public IAuthenticationHandler PriorHandler { get; set; }
|
public IAuthenticationHandler PriorHandler { get; set; }
|
||||||
|
|
||||||
|
public bool Faulted { get; set; }
|
||||||
|
|
||||||
protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpContext context)
|
protected async Task BaseInitializeAsync(AuthenticationOptions options, HttpContext context)
|
||||||
{
|
{
|
||||||
_baseOptions = options;
|
_baseOptions = options;
|
||||||
|
|
@ -94,12 +96,29 @@ namespace Microsoft.AspNet.Security.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called once per request after Initialize and Invoke.
|
/// Called once per request after Initialize and Invoke.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>async completion</returns>
|
/// <returns>async completion</returns>
|
||||||
internal async Task TeardownAsync()
|
internal async Task TeardownAsync()
|
||||||
{
|
{
|
||||||
await ApplyResponseAsync();
|
try
|
||||||
|
{
|
||||||
|
await ApplyResponseAsync();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await TeardownCoreAsync();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Don't mask the original exception
|
||||||
|
}
|
||||||
|
UnregisterAuthenticationHandler();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
await TeardownCoreAsync();
|
await TeardownCoreAsync();
|
||||||
UnregisterAuthenticationHandler();
|
UnregisterAuthenticationHandler();
|
||||||
}
|
}
|
||||||
|
|
@ -217,15 +236,29 @@ namespace Microsoft.AspNet.Security.Infrastructure
|
||||||
|
|
||||||
private void ApplyResponse()
|
private void ApplyResponse()
|
||||||
{
|
{
|
||||||
LazyInitializer.EnsureInitialized(
|
// If ApplyResponse already failed in the OnSendingHeaderCallback or TeardownAsync code path then a
|
||||||
ref _applyResponse,
|
// failed task is cached. If called again the same error will be re-thrown. This breaks error handling
|
||||||
ref _applyResponseInitialized,
|
// scenarios like the ability to display the error page or re-execute the request.
|
||||||
ref _applyResponseSyncLock,
|
try
|
||||||
() =>
|
{
|
||||||
|
if (!Faulted)
|
||||||
{
|
{
|
||||||
ApplyResponseCore();
|
LazyInitializer.EnsureInitialized(
|
||||||
return Task.FromResult(0);
|
ref _applyResponse,
|
||||||
}).GetAwaiter().GetResult(); // Block if the async version is in progress.
|
ref _applyResponseInitialized,
|
||||||
|
ref _applyResponseSyncLock,
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
ApplyResponseCore();
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}).GetAwaiter().GetResult(); // Block if the async version is in progress.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Faulted = true;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void ApplyResponseCore()
|
protected virtual void ApplyResponseCore()
|
||||||
|
|
@ -240,13 +273,27 @@ namespace Microsoft.AspNet.Security.Infrastructure
|
||||||
/// or later, as the last step when the original async call to the middleware is returning.
|
/// or later, as the last step when the original async call to the middleware is returning.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private Task ApplyResponseAsync()
|
private async Task ApplyResponseAsync()
|
||||||
{
|
{
|
||||||
return LazyInitializer.EnsureInitialized(
|
// If ApplyResponse already failed in the OnSendingHeaderCallback or TeardownAsync code path then a
|
||||||
ref _applyResponse,
|
// failed task is cached. If called again the same error will be re-thrown. This breaks error handling
|
||||||
ref _applyResponseInitialized,
|
// scenarios like the ability to display the error page or re-execute the request.
|
||||||
ref _applyResponseSyncLock,
|
try
|
||||||
ApplyResponseCoreAsync);
|
{
|
||||||
|
if (!Faulted)
|
||||||
|
{
|
||||||
|
await LazyInitializer.EnsureInitialized(
|
||||||
|
ref _applyResponse,
|
||||||
|
ref _applyResponseInitialized,
|
||||||
|
ref _applyResponseSyncLock,
|
||||||
|
ApplyResponseCoreAsync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
Faulted = true;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,25 @@ namespace Microsoft.AspNet.Security.Infrastructure
|
||||||
{
|
{
|
||||||
AuthenticationHandler<TOptions> handler = CreateHandler();
|
AuthenticationHandler<TOptions> handler = CreateHandler();
|
||||||
await handler.Initialize(Options, context);
|
await handler.Initialize(Options, context);
|
||||||
if (!await handler.InvokeAsync())
|
try
|
||||||
{
|
{
|
||||||
await _next(context);
|
if (!await handler.InvokeAsync())
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
handler.Faulted = true;
|
||||||
|
await handler.TeardownAsync();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Don't mask the original exception
|
||||||
|
}
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
await handler.TeardownAsync();
|
await handler.TeardownAsync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue