gpt4 book ai didi

c# - 异常处理中间件和页面

转载 作者:太空狗 更新时间:2023-10-29 20:09:25 25 4
gpt4 key购买 nike

我是中间件概念的新手,目前正在努力寻找在我的 MVC 核心项目中处理异常的正确方法。

我想要发生的是捕获、记录异常,然后将用户发送到带有消息的友好错误页面。起初,我试图在中间件中管理所有这些,但意识到我可能做得不对。

因此,如果我希望这个流程发生,我是否应该同时使用我的异常记录中间件和 app.UseExceptionHandler("/Error") 以便中间件将异常重新抛出到页面?如果是这样,我如何在错误页面中获取异常详细信息?并且我想先拦截的异常处理机制应该是Configure中的最后一个是否正确?

我发现的所有示例都严格处理 404 等 HTTP 状态代码错误;我正在寻找处理实际异常(及其子类)的方法。这样,在我的 View 页面中,我可以在适用的地方抛出我自己的异常(例如,如果 View 为必填字段提供了 null。)

Startup.cs 片段:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory, LoanDbContext context) {
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();

app.UseStatusCodePages();
if (env.IsDevelopment() || env.IsEnvironment("qa")) {
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
} else {
app.UseExceptionHandler("/Error");
}
app.UseMiddleware<MyExceptionHandler>(loggerFactory);
// ... rest of Configure is irrelevant to this issue

MyExceptionHandler.cs

using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace MyCompany.MyProject.Helpers
{
/// <summary>
/// A custom Exception Handler Middleware which can be re-used in other projects.
/// </summary>
public sealed class MyExceptionHandler
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;

public MyExceptionHandler(RequestDelegate next, ILoggerFactory loggerFactory) {
_next = next;
_logger = loggerFactory.CreateLogger<MyExceptionHandler>();
}

public async Task Invoke(HttpContext context) {
try {
await _next(context);
} catch (Exception ex) {
HandleException(ex);
}
}

// I realize this function looks pointless, but it will have more meat to it eventually.
public void HandleException(Exception ex) {
if (ex is ArgumentException argEx) {
_logger.LogError(0, argEx, argEx.Message);
} else if (ex is InvalidOperationException ioEx) {
_logger.LogError(0, ioEx, "An Invalid Operation Exception occurred. This is usually caused by a database call that expects "
+ "one result, but receives none or more than one.");
} else if (ex is SqlException sqlEx) {
_logger.LogError(0, sqlEx, $"A SQL database exception occurred. Error Number {sqlEx.Number}");
} else if (ex is NullReferenceException nullEx) {
_logger.LogError(0, nullEx, $"A Null Reference Exception occurred. Source: {nullEx.Source}.");
} else if (ex is DbUpdateConcurrencyException dbEx) {
_logger.LogError(0, dbEx, "A database error occurred while trying to update your item. This is usually due to someone else modifying the item since you loaded it.");
} else {
_logger.LogError(0, ex, "An unhandled exception has occurred.")
}
}
}
}

最佳答案

should I use both my Exception-logging middleware AND the app.UseExceptionHandler("/Error") so that the middleware re-throws the exception to the page?

是的。

仅使用示例的一个片段。

public async Task Invoke(HttpContext context) {
try {
await _next(context);
} catch (Exception ex) {
HandleException(ex);
// re -throw the original exception
// after logging the information
throw;
}
}

以上将在记录原始错误后重新抛出它,以便管道中的其他处理程序将捕获它并进行开箱即用的处理。

来源Error Handling in ASP.NET Core

how do I get the exception details in the Error page?

使用IExceptionHandlerPathFeature获取异常和路径

public IActionResult Error()
{
// Get the details of the exception that occurred
var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

if (exceptionFeature != null)
{
// Get which route the exception occurred at
string routeWhereExceptionOccurred = exceptionFeature.Path;

// Get the exception that occurred
Exception exceptionThatOccurred = exceptionFeature.Error;

// TODO: Do something with the exception
// Log it with Serilog?
// Send an e-mail, text, fax, or carrier pidgeon? Maybe all of the above?
// Whatever you do, be careful to catch any exceptions, otherwise you'll end up with a blank page and throwing a 500
}

return View();
}

来源Adding Global Error Handling and Logging in ASP.NET Core with IExceptionHandlerPathFeature

在上面的示例中,他们提到在 View 中进行日志记录,但您应该已经在自定义处理程序中完成了。

在呈现错误 View 时要特别注意这个小注释。

Whatever you do, be careful to catch any exceptions, otherwise you'll end up with a blank page and throwing a 500

通过插入管道,您可以避免重新发明框架已经提供的开箱即用的功能,还可以管理横切关注点。

关于c# - 异常处理中间件和页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44791206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com