错误发生的深刻的下一个数据访问层或甚至更高,(在说ADO.net 作为例)很少有太大的意义来终用户。只是起泡的这些错误达到一个用户界面,并显示他们通常会实现什么,除了挫折为一个终端用户。

我最近采用的基本技术用于报告错误,例如这个由此我赶上的错误,并至少增加一些用户友好的文本,以便至少终端用户了解什么失败。

要做到这一我醒目的例外在每个特定功能(例如说提取功能在数据访问层),然后提出新的错误的用户友好的文本有关的功能已经失败,可能引起的,但后嵌入的原始异常在新的异常作为"内部异常"的新的例外。

这个可以然后出现在每一层如果有必要,每个消费者的较低水平的功能增加它自己的背景下来的错误信息,这样,什么样的到达是一个越来越多的用户友好的错误信息。

一次错误达到UI-如果有必要的-这可以再循环的嵌套的例外情况,以便显示错误信息,首先是告诉用户操作失败,而且还提供了一位技术的信息实际上是错误的。

例如

"列表中的客户的名字你的 要求不可能显示的。"

"获取的客户名单 你要失败,因为一个错误,错误的数据库。"

"有一个错误连接的 数据库检索时的一个列表中的 客户"

"登录失败,用户xx"

我的问题是这个:这是可怕的效率低下(所有这些嵌套的例外情况)?我怀疑它是不是最佳实践所以我应该怎么做来实现同样的事情-或者我应该在实际上是努力实现更好的东西?

有帮助吗?

解决方案

这有点可怕。

如果您向最终用户显示错误,则该用户应该能够对其采取行动。在“无法显示您请求的客户名称列表”中。例如,您的用户只会想到“那么什么?”在所有这些情况下,只显示“发生了一些不好的事情”。信息。你甚至不需要捕获这些异常,当出现问题时,让一些全局方法(如application_error)处理它并显示一般消息。当您或您的用户可以对错误采取措施时,请抓住并执行操作或通知用户。

但您需要记录您未处理的每个错误。

顺便说一下,显示有关错误的信息可能会导致安全漏洞。攻击者对你的系统了解得越少,他们就越不可能找到破解它的方法(记住那些消息,比如“sql语句中的语法错误:选择*来自用户,其中username ='a'; drp数据库; - '。 ..“expect:'drop'而不是'drp'。他们不再制作这样的网站了。)

其他提示

它在技术上是成本高昂引发新的例外,但是我不会让一大的辩论出的,由于"高昂"是相对的-如果你扔100个这样的例外一分钟,你将可能看不到的费用;如果你扔1000这种例外的第二个,你很可能会看到一个能打的(因此,不是真的值得讨论在这里,性能是你的呼叫)。

我想我必须要问为什么这种方法被使用。这真的是真的,你可以添加有意义的异常的信息 平凡的一个例外可能是引,如果是的话,它也确信息将是:

  • 实际上你的东西 享用你的用户?
  • 你的东西用户将能够理解、了解和 使用?
  • 写在这样一种方式,它不会干扰今后重复使用的低等级的组件,用其可能不知道的时候他们写的?

我要求关于共享信息的用户,因为在您的例子,你的人工堆启动通知的用户有一个问题进行身份验证的数据库。对于一个潜在的黑客,这是一个很好的信息,揭露了一些关于什么动作。

作为交回整个定义的例外堆,我不认为它的东西,将是有用的,大多数(诚实的)的用户。如果我有麻烦让一个名单的客户名称,例如,它将帮助我(作为用户)知道曾经有一问题进行身份验证的数据库?除非你使用集成身份验证,并且每个用户账户,并能够接触一个系统管理员,以找出为什么他们的帐户缺乏权限,大概不会。

我会开始的第一个决定,如果真的是有一个语义之间的差框架引发的异常和异常消息你想提供给用户。如果有,然后继续前进和使用定义的异常低的水平('的登录失败的例子)。步骤以下,实际演示文稿的例外,真的不需要任何定义的例外情况。除你有兴趣在已经产生(登录失败)-继续包装的消息,在每一个级别的呼堆没有任何真正的目的以外的其他暴露你的电话堆到你的用户。对于那些"中的"步骤,假定的任何尝试/抓块是在地方,一个简单的记录,并抛出战略会工作的罚款。

真的,不过,这一战略的另一个潜在缺陷:它的部队后,开发商将负责维护的定义的例外标准,该标准已经实现。因为你不可能知道每一个置换电话的层次结构的时候写的低水平类型(他们的"客户"可能甚至已经写入尚)的,它似乎不可能的,所有开发人员--或甚至是一个开发人员将记得,以包装和定义的任何错误,条件是在每个代码块。

而不是工作从下往上,我通常担心显示的丢例外情况如下旬在该过程中尽可能(即作为近的"顶级"的呼堆作为可能)。通常情况下,我不试图取代的任何消息引发的异常低的水平,我的应用,特别是因为使用这些低级别的成员往往获得更多和更抽象的更深入的呼吁。我倾向于抓住并记录例外情况在业务层和低,然后处理显示他们在一种易于理解的方式表示层。

这里有几个体面的条款的例外处理的最佳做法:

http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx

http://aspalliance.com/1119

天哪这得罗嗦...道歉。

是的,异常是昂贵的,因此捕获和重新抛出或抛出更有用的异常会产生成本。

但等一下!如果你正在使用的框架代码或库引发异常,那么事情就已经不复存在了。您是否对异常后传播错误消息的速度有非功能性要求?我对此表示怀疑。这真的很重要吗?发生了无法预料和“特殊”的事情。主要是向用户提供合理,有用的信息。

我认为你正在做正确的事情。

当然,效率非常低。但是,如果发生的异常非常重要,可以向最终用户展示,那么您就不应该关心它了。

在我工作的地方,我们只有几个理由来捕捉异常。我们只在......时才这样做。

  1. 我们可以为此做点什么 - 例如我们知道这有时会发生,我们可以在代码中纠正它(非常罕见)。

  2. 我们想知道它发生在哪里(然后我们只是重新抛出异常)。

  3. 我们想要添加一条友好的消息,在这种情况下,我们将原始异常包装在从应用程序异常派生的新的excpetion中,并向其中添加一条友好的消息,然后让它从那时起保持不变。

  4. 在您的示例中,我们可能只显示“已发生登录错误”。 anbd在记录真实错误的同时将其留在那里,并为用户提供了如果他们也想要钻取异常的原因。 (也许是错误表单上的按钮)。

    1. 我们希望完全抑制异常并继续前进。毋庸置疑,我们只对预期的异常类型执行此操作,并且只有在没有其他方法来检测生成异常的条件时才会这样做。

一般当你处理例外情况外,性能和效率是至少你的忧虑。你应该更关心的是在做些什么来帮助用户从中恢复的问题。如果有一个问题编写一定记录的数据库,要么是滚的变回或至少倾倒的行信息,以便用户不会失去它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top