1

除了日志记录,什么构成处理异常?我问人们说只捕获你可以处理的异常。

例如,我编写了一个与 Active Directory 交互的工具。我在域控制器上运行它。由于我对 AD 有深入的了解,因此我可以处理其他例外情况(例如,我可以提出要求另一个域名的提示)并从那里开始。但是,如果生产服务器上的域存在如此关键的问题,这不是例外吗?

所以在这种情况下,环境问题应该是异常的(考虑到生产和广告等),但这是我可以处理的。我认为处理异常取决于节目观众(同意)?

无论如何,主要问题:要推断我是否可以“处理”异常,我需要知道处理需要什么 - 除了记录并向用户提供另一种选择(在这种情况下,我通过使用 if file exists 等来避免异常)。

对于上述情况(AD),我将我的代码构造为:

if (adIsAvailable)
  // do whatever here

else
  raise exception and ask for action

然后在 gui 中被捕获

关于该设计的有效性的任何想法?

4

2 回答 2

1

好问题。请记住,您只能处理特定类型的异常,并将真正关键的异常传播到堆栈中并被遗忘。

异常处理的一种用法是与用户交互,当然,正如您所说,最好的方法是检查一个前提条件,如果违反(文件不存在)将抛出异常,而不是执行实际任务并依赖关于通知的异常机制。

异常处理的另一种用法是重试。例如,您正在向数据库发送查询并收到 TimeOutException,或另一个指示连接暂时不可用的错误。在这种情况下,您可能需要稍等片刻,然后再试一次。并且仅当您在 3 次之后未能到达 Db 时 - 将异常传播到上层。

处理异常的另一种方法是将数据添加到异常或更改其类型。您可能希望捕获 TimeOutException 但抛出 MyApplicationException,其中包含例如您尝试执行的 SQL(原始异常是内部异常)。

此外,您可能想要做相反的事情 - 从异常中删除数据,例如堆栈跟踪,这是出于安全原因(将应用程序的内部工作暴露给恶意用户是不明智的)

顺便说一句,在您的情况下,您可能希望格式化用户友好的消息,清楚地说明问题的性质,而不是向用户呈现堆栈跟踪和晦涩的消息。这是可以在异常处理期间完成的转换的另一个示例。

不久前,我的应用程序抛出了一个异常,该异常是由于 DML 操作的表空间空间不足而引起的。用户遇到了一个带有错误代码的可怕异常。我所做的是添加一个处理程序来检查调用命令引发的异常,并为此错误代码添加特殊处理——它现在可以准确地告诉用户问题出在哪里!

于 2012-07-25T21:25:38.157 回答
1

在这里,您有几个不同的问题。

  1. 如何处理(并决定何时处理)底层代码抛出的异常
  2. 何时自己抛出异常
  3. 生产代码是否应该与开发代码不同地处理“异常”情况。代码。

关于第(1)点:

这可能有点混乱且难以决定——不同的 API 可能会以不同的方式使用异常,即使在同一种语言中也是如此。

例如,在 C# 中,如果我希望我的输入可能无法解析,我更喜欢使用int.TryParse()而不是int.Parse()捕获 a FormatException,并且我想编写代码来处理这种情况。

如果我不想处理错误的输入,我将使用int.Parse(), 并让异常传播。

这取决于情况,唉。

关于第(2)点:

例外基本上意味着“我放弃”。他们的意思是出了点问题,但你不会在那里自己处理。

关于第(3)点:

我认为这几乎总是一个坏主意。

在旁边:

我不同意Vitality 的部分回答,它说:

最好的方法是检查一个前提条件,如果违反(文件不存在)会抛出异常,而不是执行实际任务并依靠异常机制进行通知。

如果您编写如下代码:

if (file_exists(x))
{ /* do something */ }
else
{ /* whatever */ }

然后你向比赛条件敞开心扉。也许文件在file_exists()检查之间被删除了,所以你的代码无论如何都会抛出异常。

或者,文件可能是在您进入该else部分后创建的。

在这种情况下,我认为最好做你想做的事情,如果出现问题,处理异常。

于 2012-07-25T21:41:53.493 回答