如何让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
,然后捕捉EConvertError
exception,当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。