我的网络服务器基于Delphi / DataSnap。 当服务器方法引发异常时,我该如何处理它?</ p>
我尝试Application.OnException
但它不起作用,因为每个连接都是一个新线程,它只适用于IDE线程。
我想管理它们以便在日志文件中添加数据。
更新
正如@Remy Lebeau所说,我无法控制线程的创建。它是一个基于DataSnap的应用程序,可用作Web Api服务器。一个TDSServerClass
个组件实例TServerMethods
类。然后,当Web连接到达时,DataSnap会创建一个新线程并调用我的TServerMethods
方法。如果在方法中引发异常,则会丢失,因为每个线程都有其堆栈。使用Application.OnException
,我只能从IDE线程中捕获未处理的异常。我想要做的是在日志文件中记录任何手持设备异常。
答案 0 :(得分:1)
来自System.Classes.TThread.FatalException文档:
如果Execute方法引发了未在该方法中捕获和处理的异常,则该线程终止并将 FatalException 设置为该异常的异常对象。应用程序可以从OnTerminate事件处理程序检查 FatalException ,以确定线程是否因异常而终止。
如果Execute
对象的TThread
方法发生异常,则会分配FatalException
属性并且线程终止。
您可以检查实现其OnTerminate
事件的线程中是否发生异常:
procedure TForm1.YourThreadTerminate(Sender: TObject);
var
ex: Exception;
begin
ex := Exception(TYourThread(Sender).FatalException);
if Assigned(ex) then
//an exception has occurred: your code here
end;
这是您可以将事件分配给线程的方法:
var
yourThread: TYourThread;
begin
yourThread := TYourThread.Create(True);
yourThread.OnTerminate := YourThreadTerminate;
yourThread.Start;
end;
答案 1 :(得分:0)
您可能需要挂钩异常处理机制本身 - JCL具有执行此操作的代码,或者您可以使用第三方库,如madExcept,EurekaLog或其他。它们还收集堆栈跟踪和其他有用的信息,以了解导致异常的原因。 我不久前在Datasnap DCOM服务器中使用JCL将未处理的异常记录到自定义事件日志中。如果您要写入文件,请注意并发访问,因为多个线程可能会尝试写入它。此外,Event Tracing for Windows(ETW)可能是一种更好的,但更复杂的方式,可以记录到文件以进行诊断。 无论如何,在这种应用程序中,最好处理“预期的”异常,并且永远不要让它们传播到通用处理程序。当然,能够捕获和记录“意外”的是有用的。