3

我的软件使用 Try Catch 来捕捉错误;最近发生了一个错误(与数据库的超时连接),并弹出 Messagebox.Show() 提醒用户该问题。这种内部软件的最终用户根本不具备 IT 知识。收到这条信息的女士问我她和谁失去了联系(我真的认为她认为这是一种精神上的“联系”,因为她看起来像一个嬉皮士)。

所以我想做的是简化错误消息。

我考虑过的事情:

我可以检查/比较 ex.Message 字符串与我想要满足的字符串列表,如果它匹配一个,我将显示简化版本。国际海事组织,不现实。

然后我想有多个捕获,如果它是某种类型,则显示简单的消息。但是我的代码会有多混乱!不仅如此,它还可能以误导性消息告终,因为并非所有(例如)TimeOutExceptions 都是相同的。

或者,我必须尝试编写自己的异常类型来满足这一点。

然后我认为,如果每个 .NET 异常都有一个关联的 ID,那将非常方便——这样,我可以用每个 ID 和我自己的好且易于准备/理解的消息编写一个很好的 case 语句。

有没有其他人考虑过这个问题,他们是否找到了合适的安排。还是只在屏幕上显示一条消息“错误 - 一封电子邮件已发送给软件供应商......”更好)?

4

4 回答 4

3

您永远不应该向最终用户显示 Exception.message。这是有助于识别错误类型的信息性文本。

任何时候你捕捉到异常,你都应该正确处理它或重新抛出/抛出另一个。如果您处于通过显示一些错误消息来处理异常的代码点,您应该能够从异常本身正确推断上下文。您可以使用适当的异常类型来创建一些基本的异常域(DatabaseException、CommunicationException),并使用错误代码在其域内进一步区分异常。

您可以使用属于 Exception 类并且是 IDictionary 类型的 Data 属性,从而用作 Exception 状态包。然后,您可以在此处存储类似 'ERR_CODE' = CONSTANT 的内容,并使用一些单点异常处理来检查错误代码,如果存在,则使用一些用户友好的输出处理异常。

您甚至可以在当前 AppDomain 中注册全局异常处理程序以捕获任何未捕获的异常并显示一些消息。这是常见的做法,但您必须意识到这种方法会破坏自然的代码流,如果发生这种情况,您将得到已处理的异常但未捕获的异常流(您没有在调用者站点上处理异常然后不知道调用失败并且行为可能无法预测)。因此,仅通过打印一些用户友好的消息并结束应用程序或终止当前用例来使用这种方法。

于 2012-10-25T08:21:04.323 回答
2

如果你写过这样的代码,catch (Exception ex)那么你做错了什么。对于异常的编码情况,您应该始终捕获特定的异常。

阅读 Eric Lippert 的“Vexing exceptions”博客条目

捕获异常并仅显示消息属于“愚蠢”的异常类别。你永远不应该拥有它们。

相反,您应该只有 Eric 阐述的其他三种类型的例外。而且您应该捕获所涉及的特定异常类型,而不是泛型Exception类型。

如果您捕获特定异常,那么您可以向最终用户提供非常合理的消息——甚至提供有关如何解决问题的信息。

更好的是,没有所有通用异常捕获您的代码将更容易调试、更清洁和更简洁。代码中错误的主要预测因素是您编写的实际代码行。编写更少的代码并减少错误。

所以我的建议是改变你的代码设计并适当地处理异常。

于 2012-10-25T08:23:41.393 回答
2

通常,您需要按类型处理异常(例如catch (SomeSpecificException)

某些派生的异常类型确实有额外的代码,例如

例如SqlException具有Number可用于控制流/信息的属性

catch (System.Data.SqlClient.SqlException sqlEx)
{
  if (sqlEx.Number == 1205) // Deadlock
     ...
  if (sqlEx.Number == -2) // = TimeOut
     ...
  // etc.
}

编辑

实际上,System.Exception 确实有一个受保护的HRESULT 属性。请参阅如何确定 System.IO.IOException 的 HResult?以及 如何在 C# 中获取异常错误代码

虽然它不能直接访问,但您可以通过Marshal.GetHRForException(ex). 不同的异常有不同的 HRESULT,例如

System.Exception :  HRESULT COR_E_EXCEPTION (0x80131500)
System.SystemException : HRESULT COR_E_SYSTEM (0x80131501)

也就是说,根据其他答案,捕获特定异常仍然是 IMO 的首选机制 - 大概 HRESULT 机制是 COM 宿醉。

于 2012-10-25T08:26:09.363 回答
0

您应该为那些只有您预期代码中可能出现的异常处理并提供有意义的消息,并且可以处理异常。任何您没有预料到的异常,都会显示一条通用消息并将消息记录到日志文件或事件日志中。您可能还想为未处理/意外异常设置策略,以便显示消息以联系支持人员并退出应用程序。

于 2012-10-25T08:21:58.757 回答