【问题标题】:Should I catch all my exceptions in the global.asax?我应该在 global.asax 中捕获所有异常吗?
【发布时间】:2011-05-17 11:59:51
【问题描述】:

如果我只是在我的 Web 应用程序中记录异常详细信息,我真的需要为每一层添加异常处理逻辑吗?为什么不让它们全部冒泡到 global.asax 的堆栈跟踪并将它们记录在那里?

【问题讨论】:

    标签: asp.net logging exception-handling global-asax


    【解决方案1】:

    我建议不要在应用程序的任何层中使用 any 异常处理逻辑,除非:

    • 该异常不是致命异常,这意味着您可以采取一些措施来恢复,或者
    • 应用程序应继续运行,并且应“忽略”异常。例如:在在线零售商处结账时,您会通过电子邮件收到收据。如果失败 - 但其他订单处理成功 - 不应向用户显示错误页面。在这里,即使出现异常,我们也希望工作流继续进行。大多数例外不属于这一类。

    当然,异常——无论它们是否致命或是否应该被“忽略”——都需要记录下来并通知开发人员。这最好通过Application.Error 事件的事件处理程序来处理。是的,这可以在 Global.asax 中完成,但我认为使用基于 HTTP 模块的方法更简洁,Health MonitoringELMAH

    我写了一篇关于这个主题的文章,我想推荐给你 - Exception Handling Advice for ASP.NET Web Applications。以下是文章摘要:

    我对在 ASP.NET 应用程序中处理异常的建议可以归结为以下准则:

    (a) 创建和使用有意义的自定义错误页面。

    (b) 通常,不要捕获异常。让他们冒泡到 ASP.NET 运行时。捕获异常有意义的一些情况包括:

    • 当有一种合理的方法可以通过执行一些替代逻辑从异常中恢复时,

    • 当应用程序工作流程的外围部分抛出异常并且该异常不应破坏整个应用程序时,并且

    • 当您需要通过抛出以原始异常作为其内部异常的新异常来在异常中包含附加信息时。

    (c) 将所有异常记录到某个持久性存储中,并在生产中发生异常时使用电子邮件(或其他某种媒体)通知开发人员。考虑使用 ELMAH 或 ASP.NET 的内置健康监控系统来促进此过程。

    【讨论】:

      【解决方案2】:

      异常应该冒泡到可以有意义的方式处理它们的任何层,注意Single Responsibility principle。例如,您的数据层不应投资于日志记录。

      Application.Error 事件是处理所有错误的好地方:即,除了记录/警告和重定向到错误页面之外不需要特殊处理的意外和/或致命错误。

      【讨论】:

        【解决方案3】:

        如果您的 Web 应用使用 Microsoft AJAX 扩展和部分回发,您至少需要在两个地方处理异常:

        1. Global.asax
        2. 您的 ScriptManager 的 OnAsyncPostBackError 处理程序

        有关 OnAsyncPostBackError 的更多信息,请查看:

        http://msforge.net/blogs/janko/archive/2008/02/13/handling-exceptions-in-asp-net-ajax.aspx

        http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.onasyncpostbackerror.aspx

        【讨论】:

          【解决方案4】:

          我说在全局上尝试捕获您在程序逻辑步骤中遗漏的错误,并将它们重定向到“错误页面”或“未找到页面”。

          所有其他不必要的错误都会向用户显示错误,并且不需要将其发送到错误页面。

          例如,在具有 2 个或更多不同模块的页面中,如果其中一个抛出错误,只需隐藏它,并显示其余的。类似的尝试在错误发生时捕获错误,并在可能的情况下以最佳的非可视方式向用户处理它们,记录它们并稍后更正它们。

          现在这个错误只发生在一个模块上,你可以在你的日志中看到它并更正它,但在你这样做之前,用户会在你的页面上看到一些东西,而不是完整的错误页面。

          【讨论】:

            【解决方案5】:

            通常我所做的是在代码中执行 try...catch,但我所做的不是登录 catch,而是通过一条消息传递它,说明错误来自哪里等。然后我使用 Elmah 来捕获所有错误并记录它们。

            这样您只需处理一个区域的日志记录并满足单一职责原则,但您可以获得更多信息用于调试目的。当您遇到似乎只发生在 500 个用户中的 1 个的数据错误时,它也会很有帮助。

            【讨论】:

            • 异常的堆栈跟踪是否没有提供足够的信息来说明错误的来源?
            • 你的权利,这应该是我所需要的。我正在做的事情有点矫枉过正。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-06-25
            • 2010-09-10
            • 2021-08-20
            • 2014-11-29
            • 1970-01-01
            • 2014-08-07
            相关资源
            最近更新 更多