gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 07:57:08 35 4
gpt4 key购买 nike

我是中间件概念的新手,目前正在为我的MVC Core项目中处理异常的正确方法而苦苦挣扎。

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

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

我发现的所有示例都严格处理HTTP状态码错误,例如404;我正在寻求处理实际的异常(及其子类)。这样,在我的“ 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



通过插入管道,您可以避免重新发明框架已经提供的现成功能,并且可以管理跨 Realm 的问题。

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

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