如何让Delphi知道我已经处理了一个exception?

我已经将Application.OnException设置为自定义exception处理程序,以便我可以logging崩溃并提供退出选项。 不过,我现在发现,即使在我已经处理的exception情况下,它也会运行,例如,validation数字input时出现的exception。 有没有办法让自定义exception处理程序只运行在未处理的exception?

编辑:事实certificate,当我在debugging器外面运行时,我得到了预期的行为。 也许这只是一个debugging器的事情。 我不觉得Delphidebugging器与exception的交互是直观的,至less可以这样说。

如果debugging器内部和外部的行为发生了变化,那么实际上并不是您的程序告诉您有关exception情况。 我在我的网站上写过这个现象:

为什么即使在写入exception处理程序之后仍然会收到错误消息?

摘录:

在默认设置下,只要程序发生exception,Delphi IDE就会通知您。 重要的是,在那个时候,你的程序的exception处理代码还没有运行。 这都是delphi本身; 它作为一个debugging器的特殊地位使得它可以在你的程序知道它之前得到程序中任何exception的第一个通知。

在你closuresDelphi的消息框之后,执行将暂停在源代码的最好的一行,Delphi可以发现代表exception的来源。 按下“运行”button,程序恢复。 控制权将传递给下一个或者除了块之外。 在恢复程序之前,您可以使用各种debugging工具。 您可以检查范围内的任何variables的值,甚至可以修改它们的值。

那么,你如何通知Delphi你已经处理了一个exception呢? 你不 – 因为你的程序还没有处理它 。 为什么debugging器不能检测你的程序是否处理exception呢? 因为要做到这一点,它需要进一步执行你的程序。 检测缺lessexception处理程序就像解决暂停问题。 确定是否要处理exception的唯一方法是让程序运行,然后查看是否处理exception。 但是到了那个时候,做任何debugging都为时已晚,所以debugging器别无select,只能在程序第一次检测到exception的时候暂停一下,然后让你找出从那里做的事情。

我的文章继续描述一些你可以避免让debugging器捕获某些exception的方法,总结在这里:

  • 使用高级断点临时禁用破解代码的某些区域的exception。
  • configurationdebugging器忽略某些类的exception(及其后代)。
  • 告诉debugging器不要通知你任何exception。
  • 完全禁用集成debugging。

还有一个选项,我没有在我的文章中包括:

  • 改变你的程序,使得exception不会首先出现。

你说你正在validation数字input。 这听起来像你正在做的事情就像调用StrToInt ,然后捕捉EConvertErrorexception,当input不是一个有效的整数。 这是validationinput的昂贵方式。 取而代之的是,使用TryStrToInt ,它会告诉你转换是否成功,或者是StrToIntDef ,它会默默地返回一个默认值而不是引发exception。 另一个select是普通的旧Val ,它试图转换一个string,如果失败,它会告诉你在string中哪个位置导致失败。 如果您希望为转换消耗尽可能多的字符,然后在下一个非数字字符处继续parsing,则Val特别有用。

从文档(Delphi 7)引用TApplication.OnException

 "Use OnException to change the default behavior that occurs when an exception is not handled by application code." 

所以:在OnException事件处理程序中只有未处理的exception可用。 你遇到的可能是Delphi IDE打破了exception。 这是(至less在Delphi 7中)可configuration的。

在Delphi 7中,你可以通过点击工具 – >debugging器选项菜单进行configuration。 然后select“语言exception”一个un-ckech“停止对delphi例外”checkbox。 但是在其他delphi版本中可能会有所不同。

另一种可能是不使用Application.OnException。 但要简单地捕捉你的“主”function中的所有exception。 这样你可以捕获所有你以前没有caching的exception,loggingexception,然后崩溃。

Application.OnException只能触发未处理的exception。 在try-except块中重新引发exception将导致exception被Application.OnException处理。 对于引发exception的inputvalidation,您可以向用户显示一条消息,然后仅在需要将其logging到错误日志中时重新引发exception。