什么是处理异常以及如何在asp.net中处理它们的最佳方法

时间:2011-03-01 04:00:47

标签: c# asp.net exception-handling webforms

首先,我已经熟悉了简单的异常处理语法,但我在询问最佳位置,最佳时间以及处理它们的最佳方法。

我正在构建一个N层应用程序。所以我认为DAL有时会产生一些错误来处理..而我刚刚了解了SqlException类,该类的处理是什么?我曾经看过一个处理SqlException的代码,然后它处理Exception!

在了解了练习以及我将要处理它们之后,我打算创建一个连接数据库并在数据库中记录错误的方法,这样我就可以解决它,但我仍然不知道是什么我应该收集哪些信息以便我确定整个情况!


我认为异常处理并不是什么大问题。但是我时不时地读到一些奇怪的建议 - 我从来没有理解 - 在问题评论中但是没有人能回答我,因为这是一些非常古老的问题!

  

“不要只是明确地抓住   例外“

     

“使用的代码   应用程序中的更高层必须   总是只抛出异常,永远不会   担心如何处理它们。“

修改

Page_Error事件和Application_Error怎么样?我看到它们是处理错误的好方法

5 个答案:

答案 0 :(得分:8)

异常处理是一个大问题,为此设计一个好的策略并不简单。

首先,一些一般规则:

  • 当正在运行的代码完全无法继续执行时会发生异常,因此可能会尝试处理一些内部异常,但最终会失败。想想TCP连接:如果损坏的数据包到达,它是一个例外,但TCP协议可以处理它。如果太多损坏,则抛出I / O或套接字异常
  • 例外情况不能始终处理。几乎在所有情况下,当您从底层图层获得异常时,您无法运行更正代码。如果您的应用程序依赖于数据库并且处于脱机状态,那么当您获得有关它的例外情况时,您只能显示错误消息
  • 例外可能是意外的,并且可能揭示设计或实施缺陷。例如,实施缺陷可能是您拥有冗余数据库的情况,但是当您无法连接到第二个镜像时,您不会尝试第二个

对于第三点,记录异常并定期分析日志以查找任何奇怪的情况非常重要。那么,让我们从具体的答案开始吧。

首先

考虑“处理”异常。当您编写每个代码行时,请考虑可能阻止其完成的可能问题,并考虑可能的纠正措施。如果可能的话。错误信息不是一种好的处理方式,这是最新的策略。

不要开始编写try-catch(Exception),但更喜欢特定的异常。如果您需要将字符串解析为数字等,那么期望FormatException,如果您需要从Object投射到您的类型InvalidCastException

编写较低级别的图层时

毫不犹豫地抛出异常!不要像许多人那样做,即。 return null或使用(如ANSI C)布尔返回值和引用参数。有例外。如果你可以处理异常(即你没有找到本地文件但是你知道你有远程备份,那么通过调用远程镜像来处理FileNotFoundException,但是如果你仍然无法连接那么最终会抛出)然后做它并尝试恢复计算,但如果你不能然后抛出。并且不要忘记抛出内部异常(如果存在),因为它有助于登录最高层。

基本上,即使你没有抓到任何东西,你仍然可以决定自己抛出异常!特别是当函数参数无效时,强烈建议这样做!

另一个不错的选择是仍然登录底层。无论发生异常,您实际上都想记录。

当您记录

请记住为邮件提供足够的严重性。如果您通过代码发现数据库处于脱机状态,那么这不是意外的异常。仍然将其记录为错误,但在调查日志时不要担心代码错误。相反,如果您发现代码无法识别的异常(NullReferenceException是一个典型示例),则以最高严重性记录,即。致命的,给予它最大的优先权!

ASP.NET的一个好策略

肯定可以基于Page.OnError方法。如果您的站点的所有页面都有基页类,那么您绝对应该覆盖该方法。在该方法中,您应首先记录您的例外。

你也不应该滥用try-catch(异常)块,因为如果你没有捕获异常,你无法使用catch处理,你必须通过OnError处理它

运行此类方法时,请勿立即考虑Server.RemoveError()。您可能希望有一个静态HTML页面用于HTTP 500错误(当未处理的异常冒泡到ASP.NET运行时时触发)向用户显示礼貌消息。

简言之

  1. 如果发生任何奇怪的事情,请不要犹豫throw在基础层中
  2. 正如你的建议所说,不要处理你无法处理的异常(如果你遇到一个你无法处理的异常,请重新抛出它)。
  3. LOG !!!!!!!!!!!!!!!!!
  4. 不要在公共网站上向最终用户披露异常详情,绝不要!默认情况下,ASP.NET会阻止它发生,但您仍然可以使用OnError来打印堆栈跟踪
  5. 使用OnErrorApplication_Error作为单一中心点来处理所有意外异常
  6. 定期检查日志以查找错误/致命消息以查找代码问题,然后考虑维护/调试/修复它

答案 1 :(得分:1)

看看elmah。它是asp.net的记录器。在一个很好的摘要页面上呈现所有错误。

http://code.google.com/p/elmah/

处理异常的最佳方法是在它们适用的特定层中。如果它是一个约束声音,例如,2个具有相同名称的用户,则应该将该气泡提升到UI并提醒用户。

违反任何业务规则也是如此。这些应该冒泡到UI,以便最终用户知道出了什么问题。

最好在DAL ......等处理SQL连接错误。

答案 2 :(得分:1)

如何/何时/何地捕获异常可能取决于您尝试做什么,难以准确捕获所有始终正确的答案。


关于您的具体问题,

  

我刚刚了解了SqlException   上课,那个班的交易是什么   ?我曾经看过一个处理这个问题的代码   然后它处理SqlException   例外!

处理你认为可能发生的特定异常的好习惯,如果你不确定这个异常是什么类型你可以只是'异常',如果你想在'SQLException'上发生特定的事情而发生其他事情一个'例外'那么编写处理这两者的代码肯定没有错。


  

“不要只是明确地抓住   例外“

我相信这是指这样的代码

try 
{
   int i = 1/0;
} 
catch(Exception e)
{
  //do nothing
}

这个例外将被捕获,但你永远不会知道它发生了,因此这不是一个好主意,并且使用该代码的人将会摸不着头脑。

答案 3 :(得分:1)

我认为您在这里要求的是针对任何应用程序的错误/异常处理策略。

我认为它包括:

位置 - 您认为发生异常的所有地方或需要更多监控的地方,如数据库调用,外部服务调用,数组使用,用户输入解析,类型转换等等...

如何 - 所有高级别图层都应该抛出异常,应该在入口点捕获它并进行处理以了解根本原因。通常,您可以在Application_Error()中执行此操作,捕获异常并将其记录以进行故障排除。如何记录异常取决于您。日志文件或数据库驱动的日志是一个基于您的要求和可用资源的选项。

答案 4 :(得分:0)

IMO除了非常罕见的情况外,我只对I / O相关代码使用异常处理,其中与服务和文件系统进行交互,其功能和维护不受我的应用程序的控制。

我一直认为使用try / catch语句以相同的方式操作程序中的逻辑(控制流),如果/ else语句工作非常糟糕的话。如果您正确使用手头的工具,可以避免最常见的例外情况。