有没有办法捕获未处理的应用程序异常并将其记录?

12

有没有办法捕获并记录应用程序中的所有错误。目前,我在我认为可能出现错误的地方使用 try catch 块。但是是否有可能在应用程序级别捕获所有错误(我的意思是,我可以将 try catch 块放在项目文件中,或者可能有其他技巧可以做到这一点)?


你需要能够定义应用程序中可能发生的每种错误类型以及发生的级别,然后将它们包含在try-catch块中并/或者以某种方式记录下来,例如记录到事件日志(假设是Windows)或日志文件中。 - Darth Continent
1
您可以使用 TApplicationEvents 组件并将某些内容分配给 OnException 事件。然后,此过程将接收所有 未处理的 异常。 - Andreas Rejbrand
为什么要捕获它们?通常你想让它们浮到顶层处理程序。 - David Heffernan
2
@David:这取决于异常情况。如果它是由您代码中的错误导致的,那么是的;让它浮现并被您的异常记录器捕获。但如果它是由您无法控制的因素引起的(例如“网络连接不可用”),则您需要找到一种处理方式,而不会在用户面前抛出错误对话框,并使其看起来像是您代码中存在错误,而实际上并非如此。 - Mason Wheeler
你的问题不够清楚。你想记录所有未处理的异常和所有已处理的异常吗?你想捕获并忽略所有异常吗?具体是什么要求? - Warren P
5个回答

28

看一下 MadExcept。如果将其添加到项目中,它会自动安装钩子来捕获所有未处理的异常,生成非常详细的错误报告,并甚至可以通过电子邮件或在线服务发布。这是接近在客户系统上附加调试器的最佳解决方案。


7
您还可以考虑使用Eureka Log,CodeGear自己也在其PHP产品中使用了它。Eureka Log还具有内存泄漏检测功能,并允许您将崩溃报告静默地发送电子邮件、ftp、自动添加到缺陷跟踪系统中,或允许交互式崩溃转储提交。
它不是免费的,但我认为它值得花钱购买。老实说,如果没有它,我无法想象使用Delphi。此外,该程序还有一个.NET版本。
我喜欢的最后一个功能是,您实际上可以配置产品以对某些异常采取不同的操作,同时仍然正常捕获其他异常。我将其与可能抛出的一些Indy异常一起使用:

我们在工作中使用EurekaLog。它的高级特性非常有用,但很多时候MadExcept也足够好,并且免费。 - Mason Wheeler
1
@Mason:MadExcept仅适用于非商业应用程序免费。请参阅:http://www.madexcept.com/madExceptShop.htm - lkessler
@lkessler:非常好的发现。我甚至没有考虑过这个区别,因为我所使用的是非商业性质的。 - Mason Wheeler

2
"捕获"异常可以有许多意思:记录它,显示它,执行操作,重新引发它或这些方式的任何组合。TApplication OnException处理程序将“捕获”所有未处理的主线程异常,但不会捕获在线程中引发的异常。为此,您需要实现自己的线程异常处理。在我的应用程序框架(http://www.csinnovations.com/framework_overview.htm)中,我编写了代码,以确保可以记录任何异常(所有未处理的异常和选择性地处理任何已处理异常),并且如果它在主线程中,则可以选择性地显示,无论它是在主线程还是任何其他线程中发生。虽然它不像MadExcept那样全面,但具有处理异常所需的所有功能。

2
如果你想要拦截所有异常并记录它们,你需要实现一个低级过程RTLUnwindProc
这有点底层(例如,需要汇编技能),因此你最好依赖于现有的代码。请参见这个Stack Overflow问题
我甚至在我的回答中放置了一些参考代码(包括低级汇编,在Delphi 7及以后版本的Win32下工作),展示了我们的开源框架中包含的日志记录功能logging features included in our Open Source mORMot framework。要记录所有异常,只需添加对的引用,并在程序启动时添加以下行:
TSynLog.Family.Level := [sllException,sllExceptionOS];

目前可以在Win32和Win64平台上使用Delphi 5到XE4进行工作。

-1

使用try..except块,像这样:

try
..
// a critical section here
..
except on E:exception do
begin
  showmessage('an error occured: ' + E.message);
  //do something else
end
end;

@Warren 这位年轻的小伙子捕获了一个异常并展示了一条消息 :) - evilone
但是对于一个代码示例的投票!!!对于新来搜索异常处理的人很有用。 - evilone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接