Reputation: 135
I am having an issue with UseExceptionHandler in .Net Core 3.1 WebApi starts failing to trigger after copying the response body to a stream. I am using a middleware to intercept incoming requests and outgoing responses for a webapi project and logs records to a table. It works fine until the stream.CopyToAsync() method is called. Any exceptions after that does not trigger the ExceptionHandler, even though a local try/catch will still catch an exception and rethrowing the exception in the catch block still doesn't cause the ExceptionHandler to trigger.
Invoke Method
public async Task Invoke(HttpContext context)
{
Stream originalBody = context.Response.Body;
try
{
using var memStream = new MemoryStream();
context.Response.Body = memStream;
await _next(context).ConfigureAwait(false);
await LogResponse(context, originalBody, memStream).ConfigureAwait(false);
}
catch (Exception ex)
{
throw ex;
}
finally
{
context.Response.Body = originalBody;
originalBody.Close();
}
}
}
LogResponse Method
private async Task LogResponse(HttpContext context, Stream originalBody, MemoryStream stream)
{
stream.Seek(0, SeekOrigin.Begin);
string body = await new StreamReader(stream).ReadToEndAsync().ConfigureAwait(false);
stream.Seek(0, SeekOrigin.Begin);
//This is the line of code that breaks UseExceptionHandling pipeline
await stream.CopyToAsync(originalBody).ConfigureAwait(false);
var resp = new ApiLogItemRequest()
{
AppName = "AppName",
CreatedBy = "AppName",
DateTime = DateTime.Now,
RawBodyJson = body,
TraceIdentifier = context.TraceIdentifier
};
await _logHelper.LogRawHttpBodyItem(resp);
}
Any thoughts or hints would be much appreciated. Thanks!
Upvotes: 0
Views: 715
Reputation: 135
I was able to figure out the issue. The originalBody
variable was null, then an exception was being thrown by the ExceptionHandler
creating a weird error loop in the middleware, causing it to fail to execute the handler's code. I'm assuming it has something to do with the context being written with a null response from the CopyToAsync()
line of code, but I'm not 100% certain on the why.
I changed the code so that it insured only copying when originalBody
is not null and it fixed the issue.
I recognized the ExceptionHandler
hang up in the debug console. ExceptionMiddleware
's Invoke
only should have been called once and done, but it was followed by HandleException
then Invoke
again which leads me to think there was some exception in the ExceptionHandler
causing it to skip out the code there.
(I didn't state originally, but the root issue was that the originalBody = context.Response.Body
was being written before _next(context);
In this case, there is no response body to copy. That logic should have occurred after _next(context)
System.Exception: Test exception
at Project.Api.Middleware.ApiRequestResponseLog.Invoke(HttpContext context) in C:\GIT\Project\Project.Api\Middleware\ApiRequestResponseLog.cs:line 82
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
//These below shouldn't have occured
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
Upvotes: 1