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

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

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

在了解了实践以及我将要处理它们之后,我计划创建一个连接数据库并在数据库中记录错误的方法,以便我可以解决它,但我仍然不知道应该提供哪些信息收集让我识别整个情况!


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

“不要只是明确地捕捉exception”

“应用程序中更高层使用的代码必须始终只抛出exception,而不必担心如何处理它们。”

编辑

那么Page_Error事件和Application_Error ..我看到它们是处理错误的好习惯

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

首先,一些一般规则:

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

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

首先

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

不要开始编写try-catch(Exception),而是更喜欢特定的exception。 如果你需要将字符串解析为数字等,那么期望FormatException ,如果你需要从Object InvalidCastException为你的类型期望InvalidCastException

编写较低级别的图层时

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

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

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

当你记录

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

ASP.NET的一个好策略

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

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

运行这样的方法时,不要立即考虑Server.RemoveError() 。 您可能更喜欢为HTTP 500错误(当未处理的exception冒泡到ASP.NET运行时时触发)的静态HTML页面向用户显示礼貌消息。

简要地

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

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

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

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

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

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

捕获exception的方式/时间/位置可能取决于您尝试做什么,难以准确捕获所有始终正确的答案。


至于你的具体问题,

我刚刚了解了SqlException类,该类的处理是什么? 我曾经看过一个处理SqlException的代码,然后它处理Exception!

处理您认为可能发生的特定exception的良好做法,如果您不确定此exception的类型,您可以只是’exception’,如果您想要在’SQLException’上发生特定的事情,并且其他事情会发生’exception’那么编写处理这两者的代码肯定没有错。


“不要只是明确地捕捉exception”

我相信这是指代这样的代码

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

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

我想你在这里问的是任何应用程序的错误/exception处理策略。

我认为它包括:

Where – 您认为exception可能发生或需要更多监控的所有地方,如数据库调用,外部服务调用,数组使用,用户输入解析,类型转换等等……

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

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

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