【问题标题】:c# How to Check if an Exception Was Already Thrownc#如何检查是否已经抛出异常
【发布时间】:2013-05-03 17:31:09
【问题描述】:

我觉得我想太多了,或者可能走错了路,但我要做的只是捕捉应用程序中抛出的错误,将它们记录到数据库中,然后重定向到一个软错误页面。

在我的 Global.asax 中,我有以下内容:

protected void Application_Error(object sender, EventArgs e)
    {
        try
        {
            ErrorLog error = new ErrorLog(Server.GetLastError().GetBaseException(), true);
            Response.Redirect("/error.aspx?id=" + error.ID);
        }
        catch(Exception err)
        {
            Response.Redirect("/error.aspx");
        }           
    }

错误日志是我创建的一个执行记录插入和类似操作的类。

现在我遇到的问题是,如果数据库出现问题,比如它处于脱机状态、存储过程中的错误等,我就会陷入插入错误的无限循环。

我试图提出解决此问题的解决方案是检查是否已引发错误,如果是,请不要尝试插入记录,但我无法找到关于这一点。

再一次,也许我没有以正确的方式解决这个问题?任何帮助将不胜感激。提前谢谢你。

【问题讨论】:

  • 也许导致数据库错误的代码会在抛出错误的情况下继续运行?
  • 你是说你的架构是“我们不会捕获任何异常,一切都会冒泡到应用程序级别”并且唯一处理错误的地方就是在这个事件中?
  • 也许我应该提到这一点。这是最后一种情况。我在应用程序中有很多其他错误处理,可以捕获错误并登录。这是针对其他地方未处理的错误。

标签: c# asp.net error-handling


【解决方案1】:

其实可以这样做,但我真的不认为这是一个好主意。

理论上你可以使用Marshal.GetExceptionPointers() 来检测它。如果返回 IntPtr.Zero,则可能表示飞行中没有异常;否则,可能意味着存在。

我说“可能”是因为 Marshal.GetExceptionPointers() 的 MSDN 文档在备注下说:

GetExceptionPointers 仅用于结构化异常处理 (SEH) 的编译器支持。

所以这对我来说听起来像是一个大胖子“不要使用这个”

有了这个附加条件,这个程序实际上会告诉你异常是否正在发生,而不需要使用 try/catch 来这样做:

警告:前面有讨厌的代码

using System;
using System.Runtime.InteropServices;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (new Test())
                {
                    // All is well.
                }

                using (new Test())
                {
                    throw new InvalidOperationException("Eeep");
                }
            }

            catch (Exception ex)
            {
                Console.WriteLine("Exception detected: " + ex.Message);
            }
        }
    }

    sealed class Test: IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine(
                Marshal.GetExceptionPointers() == IntPtr.Zero
                ? "Disposing test normally."
                : "Disposing test because of an exception.");
        }
    }
}

【讨论】:

    【解决方案2】:

    您可以检查您是否已经在该页面上,并且仅当您不是时才重定向:

    string cTheFile = HttpContext.Current.Request.Path;
    
    if(!cTheFile.EndsWith("error.aspx", StringComparison.InvariantCultureIgnoreCase))
        Response.Redirect("/error.aspx");
    

    【讨论】:

    • 好吧,它永远不会到达重定向语句。我在 ErrorLog 类中进行了一个 db 调用,如果那里有问题,那么它会冒泡到 Application_Error,尝试记录它并开始循环。
    • @StanleyJenkins 不重定向将停止此代码...检查一下 :)
    【解决方案3】:

    使用 ErrorLogDBInsertException 覆盖 Exception 类,如果 DB 出现问题,则抛出该类。捕获特定错误

    protected void Application_Error(object sender, EventArgs e)
    {
        try
        {
            ErrorLog.Log();
            Response.Redirect("/error.aspx?id=" + error.ID);
        }
        catch(ErrorLogDBInsertException err)
        {
    
            try 
            {
                // here you can log into event log
            }
            catch {}
            Response.Redirect("/SimpleNoDBCallPage_error.aspx");
    
        } 
        catch(Exception err)
        {
            Response.Redirect("/PageThatCallsDB_error.aspx");
        }           
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 2021-06-07
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多