[英]How to configure multiple exception handlers
I am trying to configure my middleware pipeline to use 2 different exception handlers to handle the same exception.我正在尝试将我的中间件管道配置为使用 2 个不同的异常处理程序来处理相同的异常。 For example, I'm trying to have both my custom handler and in-built DeveloperExceptionPageMiddleware as follows:
例如,我试图让我的自定义处理程序和内置的 DeveloperExceptionPageMiddleware 如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.ConfigureCustomExceptionHandler();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.ConfigureCustomExceptionHandler();
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
My objective is to have the custom handler do its own thing (logging, telemetry, etc), and then pass on (next()) to the other in-built handler which displays a page.我的目标是让自定义处理程序做自己的事情(日志记录、遥测等),然后将 (next()) 传递给其他显示页面的内置处理程序。 My custom handler looks like this:
我的自定义处理程序如下所示:
public static class ExceptionMiddlewareExtensions
{
public static void ConfigureCustomExceptionHandler(this IApplicationBuilder app)
{
app.UseExceptionHandler(appError =>
{
appError.Use(async (context, next) =>
{
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if (contextFeature != null)
{
//log error / do custom stuff
await next();
}
});
});
}
}
I cannot get CustomExceptionHandler to pass on processing to the next middleware.我无法让 CustomExceptionHandler 将处理传递给下一个中间件。 I get the following page instead:
我得到以下页面:
404 error: 404错误:
I tried switching around the order, but then the developer exception page takes over and the custom exception handler is not called.我尝试切换顺序,但随后开发人员异常页面接管并且未调用自定义异常处理程序。
Is what I'm trying to do possible at all?我正在尝试做的事情可能吗?
Update:更新:
The solution was to take Simonare's original suggestion and re-throw the exception in the
Invoke
method.解决方案是采用 Simonare 的原始建议,并在
Invoke
方法中重新抛出异常。 I also had to remove any type of response-meddling by replacing the following inHandleExceptionAsync
method:我还必须通过替换
HandleExceptionAsync
方法中的以下内容来删除任何类型的响应干预:
context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)code; return context.Response.WriteAsync(result);
with:
和:
return Task.CompletedTask;
Instead of calling two different Exception Handling Middleware, you may consider to add logging under your Home/Error
您可以考虑在
Home/Error
下添加日志记录,而不是调用两个不同的异常处理中间件
[AllowAnonymous]
public IActionResult Error()
{
//log your error here
return View(new ErrorViewModel
{ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
alternatively, you can use custom Expception Handling Middleware 或者,您可以使用自定义的Expception Handling Middleware
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context, IHostingEnvironment env)
{
try
{
await _next(context);
}
catch (Exception ex)
{
if (!context.Response.HasStarted)
await HandleExceptionAsync(context, ex, env);
throw;
}
}
private Task HandleExceptionAsync(HttpContext context, Exception exception, IHostingEnvironment env)
{
var code = HttpStatusCode.InternalServerError; // 500 if unexpected
var message = exception.Message;
switch (exception)
{
case NotImplementedException _:
code = HttpStatusCode.NotImplemented;
break;
//other custom exception types can be used here
case CustomApplicationException cae: //example
code = HttpStatusCode.BadRequest;
break;
}
Log.Write(code == HttpStatusCode.InternalServerError ? LogEventLevel.Error : LogEventLevel.Warning, exception, "Exception Occured. HttpStatusCode={0}", code);
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return Task.Completed;
}
}
and Simply Register it inside IApplicationBuilder Method 并简单地在IApplicationBuilder方法中注册它
public void Configure(IApplicationBuilder app)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
}
Here's a very simple version of how to use custom exception handling logic WITH the built-in ASP.NET Core error page at the same time:这是一个非常简单的版本,说明如何同时使用自定义异常处理逻辑和内置的 ASP.NET Core 错误页面:
app.UseExceptionHandler("/Error"); //use standard error page
app.Use(async (context, next) => //simple one-line middleware
{
try
{
await next.Invoke(); //attempt to run further application code
}
catch (Exception ex) //something went wrong
{
//log exception, notify the webmaster, etc.
Log_Exception_And_Send_Email_or_Whatever(ex);
//re-throw the exception so it's caught by the outer "UseExceptionHandler"
throw ex;
}
});
PS Uhmm, I added an explicit language: c#
hint to my answer but syntax highlighting still does not see catch
as a keyword... Interesting. PS 嗯,我在我的答案中添加了一个显式
language: c#
提示,但语法突出显示仍然没有将catch
视为关键字......很有趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.