.net core custom exception middleware
Foreword
In programming, we will encounter various exception problems. A good exception handling solution can help developers quickly locate problems and give users a better user experience.
Several ways of exception handling
1. Capture exceptions through exception filters for processing
2. Customized exception handling middleware
Here I choose to customize the exception handling middleware. The middleware relies on the request pipeline to run, and the execution of the middleware is orderly and isolated from the business. Placing the middleware in the request pipeline can capture the global situation. abnormal.
Exception middleware definition
We first create a new class to save the result information
public abstract class AjaxResponseBase
{
public string TargetUrl { get; set; }
public bool Success { get; set; }
public ErrorInfo Error { get; set; }
public bool UnAuthorizedRequest { get; set; }
public string StatusCode { get; set; }
}
Definition of middleware
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public ExceptionMiddleware(RequestDelegate next
, ILoggerFactory loggerFactory
{
_next = next;
_logger = loggerFactory.CreateLogger();
}
public async Task Invoke(HttpContext context)
{
ExceptionDispatchInfo edi;
try
{
var task = _next(context)
//Determine whether subsequent middleware processing is successfully completed, if not, catch the exception
if (!task.IsCompletedSuccessfully)
{
//Record exception information
await Awaited(context, () => task);
}
return;
}
catch (Exception ex)
{
edi = ExceptionDispatchInfo.Capture(ex);
}
//Note that we did not throw an exception here,
await HandlerException(context, edi);
}
private async Task HandlerException(HttpContext context, ExceptionDispatchInfo edi)
{
if (context.Response.HasStarted)
{
// The response begins and an exception is thrown to terminate the response.
edi.Throw();
}
//Record exception information and write exception information into the response body
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var requestPath = context.Request.Path;
var exception = edi.SourceException;
var logMsg = $"SourseRoute {requestPath} {exception.Source} {exception.Message} {exception.StackTrace} ";
_logger.LogError(logMsg);
AjaxResponse response = new AjaxResponse();
response.Success = false;
response.StatusCode = "500";
ErrorInfo error = new ErrorInfo();
response.Error = error;
error.Error = logMsg;
await context.Response.WriteAsJsonAsync(response);
}
//Catch exceptions in subsequent pipelines
private async Task Awaited(HttpContext context, Func func)
{
ExceptionDispatchInfo?edi = null;
try
{
await func.Invoke();
}
catch (Exception exception)
{
edi = ExceptionDispatchInfo.Capture(exception);
}
if (edi != null)
{
await HandlerException(context, edi);
}
}
}
use
Note that please place the middleware at the beginning of the request pipeline so that global exceptions can be captured and recorded
app.UseMiddleware();
Throw an exception in the controller
You can see that we have recorded the exception information and printed it out when swagger requested the controller
Comparison of middleware and exception filters
Both can be used to catch program exceptions, but the scope of catching exceptions is different. As a type of filter, IExceptionFilter can only capture exceptions inside the controller. If our exception occurs outside the controller, it cannot be captured. Placing the exception middleware first in the request pipeline can capture global exceptions. abnormal.
Finally, if there are any deficiencies, please give me some advice