除了记录,处理异常的构成是什么?我问,因为人们说只能抓住你可以处理的例外。
例如,我编写了一个与Active Directory交互的工具。我在域控制器上运行它。由于我对AD有深入的了解,我可以处理一个特殊情况(例如,我可以提出询问另一个域名的提示)并从那里开始。但是,如果生产服务器上的域存在问题如此关键,这不是特例吗?
所以在这种情况下,环境问题应该是例外(假设是生产和AD等),但这是我可以处理的。我认为处理异常取决于程序受众(同意)?
无论如何,主要问题是:推断我是否可以“处理”异常,我需要知道什么句柄需要 - 除了记录并向用户提供另一个选择(在这种情况下,我通过使用if文件存在来避免异常)等)。
对于上述情况(AD),我将代码结构化为:
if (adIsAvailable)
// do whatever here
else
raise exception and ask for action
然后在gui中抓住了
有关该设计有效性的任何想法?
答案 0 :(得分:1)
好问题。 请记住,您只能处理特定类型的异常,并将真正关键的异常传播到堆栈中并被遗忘。
异常处理的一种用法是与用户交互,当然,正如你所说,最好的方法是检查一个先决条件,即如果违反(文件不存在)将抛出异常,而不是执行实际任务并依赖于通知的异常机制。
异常处理的另一种用法是重试。例如,您正在向DB发送查询并接收TimeOutException,或者指示该连接暂时不可用的另一个错误。在这种情况下,您可能需要等待一段时间,然后再尝试一次。并且只有在你没有达到Db之后,比如3次 - 将异常传播到上层。
处理异常的另一种方法是将数据添加到异常或更改其类型。 您可能希望捕获TimeOutException,但抛出一个MyApplicationException,其中包含您尝试执行的SQL(原始异常是内部异常)。
此外,您可能希望执行相反的操作 - 从异常中删除数据,例如堆栈跟踪,这是出于安全原因(将应用程序的内部工作方式暴露给恶意用户是不明智的)
顺便说一句,在您的情况下,您可能希望格式化一个明确说明问题性质的用户友好消息,而不是向用户显示堆栈跟踪和模糊消息。这是可以在异常处理期间完成转换的另一个示例。
不久前,我的应用程序抛出了异常,该异常是在DML操作的表空间中空间不足而引起的。用户遇到错误代码的可怕异常。我所做的是添加一个处理程序,检查从命令调用中抛出的异常,并为此错误代码添加了特殊处理 - 它现在告诉用户确切的问题是什么!
答案 1 :(得分:1)
这里有几个不同的问题。
关于第(1)点:
这可能有点混乱且难以决定 - 不同的API可能会以不同的方式使用异常,即使在同一种语言中也是如此。
例如,在C#中,如果我希望我的输入可能无法解析,我更喜欢使用int.TryParse()
而不是int.Parse()
并捕获FormatException
,我想编写代码处理那个案子。
如果我不想处理错误的输入,我将使用int.Parse()
,并让异常传播。
这取决于具体情况,唉。
关于第(2)点:
例外基本上意味着"我放弃"。他们的意思是出了问题,但你自己也不会自己处理它。
关于第(3)点:
我认为这几乎总是一个坏主意。
<强>除了:强>
我不同意Vitality's answer的部分内容,其中包含:
最好的方法是检查是否违反的前提条件(文件确实如此) 将不存在)将抛出异常,而不是执行实际 任务并依赖于通知的异常机制。
如果您编写如下代码:
if (file_exists(x))
{ /* do something */ }
else
{ /* whatever */ }
然后你打开自己的竞争条件。
可能在file_exists()
检查之间删除了文件,因此您的代码无论如何都会抛出异常。
或者可能在您输入else
部分后创建了文件。
在这种情况下,我认为做你想做的事情会更好,如果出现问题,可以处理异常。