首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MadExcept +尝试/最后阻止?

MadExcept +尝试/最后阻止?
EN

Stack Overflow用户
提问于 2014-07-08 23:31:20
回答 2查看 1.2K关注 0票数 3

我有一些delphi代码,有点像这样:

代码语言:javascript
复制
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-除了添加到项目中进行错误故障排除之前,这段代码是“工作的”。但是现在我得到了bug报告,因为MadExcept报告了这个不寻常的异常。

相关问题,MadExcept triggers on try finally表示在这种情况下,由于异常未被“处理”,MadExcept的破坏行为是“预期的”。

我想要澄清一下,我的选项是如何防止疯狂的--除了在这段代码运行时弹出的对话框之外,不管是否有内部异常被抛出或忽略。

所以,我认为没有开关可以阻止MadExcept在try/finally块中打开未处理的异常,这是正确的吗?我需要明确地“抓住”这个例外,即使我想忽略它?

我是否应该这样做(忽略任何例外):

代码语言:javascript
复制
try
  //some code
  //sometimes throws EIndexOutOfRangeException here
  //more code...should get skipped if exception is thrown
except do begin end;
end;

或者(忽略一个非常具体的例外):

代码语言:javascript
复制
try
  //some code
  //sometimes throws EIndexOutOfRangeException here
  //more code...should get skipped if exception is thrown
except on E : EIndexOutOfRangeException do begin end;
end;

或者应该是:

代码语言:javascript
复制
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;

如果这三者都是有效的解决方案,我是否应该因为任何原因而选择一个而不是另一个呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-08 23:58:57

所以,我认为没有开关可以阻止MadExcept在try/finally块中打开未处理的异常,这是正确的吗?

是。try/finally不是异常处理;无论是否发生异常,它都可以保证清理。因此,try/finally块与异常处理工具(如MadExcept )完全无关。

我需要显式地“捕获”异常,即使我想忽略它?

是。例外情况就是这样运作的。他们一直往下走,直到找到一个能抓住他们的处理程序。如果不存在此类处理程序,则操作系统将其解释为崩溃并终止程序。Delphi的TApplication对象在调用堆栈底部安装一个处理程序,以便您的程序不会崩溃,而MadExcept会将其挂钩,以便当异常到达此点时,将生成一个报告。

如果您想忽略一个异常,是的,您确实需要捕获它,因为您正在做的是正式地“通过在堆栈展开和忽略它的此时捕获它来处理异常”。关于“在堆栈展开中此时捕获它”的部分很重要,因为这意味着堆栈展开在该点停止,程序恢复正常执行。如果你对此置之不理。在您的代码中没有做任何事情,包括没有安装异常处理程序,它将继续将堆栈解压到默认处理程序,不管您是否安装了MadExcept。

所以是的,在这种情况下,例子2是正确的行动方针。如果您有需要在此时执行的清理代码,则示例3也是有效的。但是,在任何情况下都不应该执行示例1,因为这意味着您可能会忽略一个您没有预料到的异常,然后您的程序就会崩溃,您永远不会意识到这一点。

票数 5
EN

Stack Overflow用户

发布于 2014-07-09 01:38:13

在我看来,你对finally的含义有一个基本的错误理解。

finally块不影响异常的传播。它只是确保finally块将执行,即使已经引发异常,或者exitbreak等修改了正常的执行流。

如果尝试/最后退出,madExcept仍然会报告程序引发了一个未被处理的异常。

有一些方法可以告诉madExcept忽略某些异常。例如,有些例外应该保持沉默。这方面的典型例子是EAbort。您可以使用RegisterExceptionHandler来自定义如何处理未处理的异常。虽然,正如我将解释的,我怀疑这是解决你的问题的办法。

接下来您需要做的是忘记madExcept。你需要想办法解决这个异常。您想在这里处理它,还是需要让异常传播?只有你才能真正知道。但madExcept不是这里的司机。驱动您的决定的是程序的正确执行。是否应该处理异常,以使程序行为正确?您必须首先正确地处理这个问题,然后再担心madExcept。

如果您需要在这里处理它,那么就有选择地处理它。不要抓住所有的例外。那是绝对不-不。但如果你在这里处理这件事,问问自己这是否明智。代码未能执行某些操作。是否有一些后续代码依赖于成功的操作?通过处理错误,并按照您的建议忽略它,您将迫使所有后续代码对此操作的成功或失败产生矛盾。对我来说这似乎是非常可疑的。

现在,例外是EIndexOutOfRangeException。这意味着您编写了类似于A[i]的东西,其中i的值无效。我想不出哪种情况是可以接受的。因此,在我看来,您的程序包含一个错误,并且只是使用无效的索引。您应该通过不超出界限的访问来正确地修复该错误。不要抑制异常,停止引发异常。

另一种看待这个的方法。如何区分当前情况与编写A[-i]而不是A[i]所产生的区别?抑制异常意味着您无法检测到这样的严重错误。

据我所知,底线是madExcept报告了代码中的一个错误。你应该把madExcept当作你的朋友,听它说什么。它告诉您,您的代码中有一个应该修复的缺陷。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24643148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档