我有一些delphi代码,有点像这样:
try
//some code
//occasionally throws an exception here, for example an EIndexOutOfRangeException
//more code...should get skipped if exception is thrown
finally
// there may or may not be any important cleanup code here
end;
在这种情况下的异常并不需要处理超出try块的处理。因此,在将mad-except添加到项目中以进行错误故障排除之前,此代码“正常工作”。但现在我收到错误报告,因为MadExcept正在报告未捕获的异常。
相关问题,MadExcept triggers on try finally表示MadExcept在这种情况下破坏的行为是“预期的”,因为异常没有“处理”。
我想澄清我的选择是什么,以防止在此代码运行时弹出疯狂的对话框,无论是否抛出内部异常并忽略它。
所以我认为没有开关禁止MadExcept打破try / finally块中的无法处理的异常?即使我想忽略它,我还是需要明确地“抓住”异常?
我应该做这样的事情(忽略任何异常):
try
//some code
//sometimes throws EIndexOutOfRangeException here
//more code...should get skipped if exception is thrown
except do begin end;
end;
或者(忽略一个非常具体的例外):
try
//some code
//sometimes throws EIndexOutOfRangeException here
//more code...should get skipped if exception is thrown
except on E : EIndexOutOfRangeException do begin end;
end;
或者可能需要:
try
try
//some code
//sometimes throws EIndexOutOfRangeException here
//more code...should get skipped if exception is thrown
except on E : EIndexOutOfRangeException do begin end;
finally
// some cleanup code
end;
如果所有这三个都是有效的解决方案,我是否应该因为某种原因而优先选择其中一个?
答案 0 :(得分:5)
所以我认为没有开关禁止MadExcept打破try / finally块中的无法处理的异常?
是。 try/finally
不是异常处理;它是保证清理,无论是否发生异常。因此,try/finally
块与MadExcept等异常处理工具完全无关。
即使我想忽略它,我还是需要明确地“捕获”异常?
是。这就是异常的工作方式。它们沿着堆栈向下工作,直到找到捕获它们的处理程序。如果不存在这样的处理程序,则操作系统将其解释为崩溃并终止程序。 Delphi的TApplication
对象安装一个非常接近调用堆栈底部的处理程序,这样你的程序就不会崩溃,而MadExcept会挂钩它,这样如果异常达到这一点,就会生成一个报告。
如果你想忽略一个异常,是的,你确实需要捕获它,因为你正在做的是正式“通过在堆栈中的这一点捕获并忽略它来处理异常”。关于“在堆栈展开时捕获它”的那一部分很重要,因为它意味着堆栈展开在该点停止并且程序恢复正常执行。如果你只是忽略它,(即在你的代码中没有做任何事情,包括不安装异常处理程序),它将继续将堆栈一直展开到默认处理程序,无论你是否安装了MadExcept。
所以是的,在这种情况下,示例#2是正确的行动方案。示例#3也是有效的,如果你有需要在此时执行的清理代码。但是示例#1 绝不应该在任何情况下完成 ,因为这意味着您可能最终会忽略您不期待的异常,然后你最终在你的程序中腐败,你永远不会意识到它。
答案 1 :(得分:2)
在我看来,你对finally
的含义有一个基本的误解。
finally
块不会影响异常的传播。它只是确保finally
块将执行,即使已引发异常,或者exit
,break
等已修改正常执行流程。
将try / finally输出,madExcept仍然会报告该程序引发了一个未处理的异常。
有一些方法可以告诉madExcept忽略某些异常。例如,一些例外应该是沉默的。这种规范的例子是EAbort
。您可以使用RegisterExceptionHandler
来自定义处理未处理的异常的方式。虽然,正如我将解释的那样,我怀疑这是你问题的解决方案。
接下来你要做的就是忘掉madExcept。您需要弄清楚如何处理此异常。你想在这里处理它,还是需要让异常传播?只有你真的知道这一点。但madExcept不是这里的驱动程序。必须推动您做出决定的是正确执行您的计划。是否应该处理异常,以使您的程序正常运行?你必须首先做到这一点,然后担心madExcept。
如果您需要在此处理,请选择性地处理它。不要抓住所有例外。这绝对是禁忌。但如果你在这里处理它,问问自己这是否合理。代码无法执行某些操作。是否有一些后续代码依赖于该操作成功?通过处理错误并按照您的建议忽略它,您迫使所有后续代码对此操作的成功或失败产生矛盾。这对我来说似乎非常可疑。
现在,例外是EIndexOutOfRangeException
。这意味着您编写了类似A[i]
的内容,其中i
的值无效。我想不出那种可以接受的情况。因此,在我看来,您的程序包含错误,并且只是使用无效索引。您应该通过不访问越界来正确修复该错误。不要压制异常,停止它被引发。
另一种看待这个的方法。您如何区分当前情况与撰写A[-i]
而不是A[i]
所产生的情况之间的差异?抑制异常意味着您无法检测到此类严重错误。
据我所知,底线是madExcept报告代码中的错误。您应该将madExcept视为您的朋友,并听取它所说的内容。它告诉您,您的代码中存在应该修复的缺陷。