Delphi Datasnap REST Server中的异常处理

J__*_*J__ 5 delphi datasnap delphi-xe3

我正在努力处理我的Datasnap REST服务中的异常处理(Delphi XE3,但也尝试使用Delphi 10 Seattle).多年来我写了六个Windows服务,我总是包含一个TApplicationEvents组件,以便我可以将任何应用程序异常记录到Windows事件日志中.

但是,Datasnap服务不会发生此行为.TApplicationEvents.OnException事件永远不会被触发,所以我假设其他东西正在吃异常并在它到达之前处理它.

Web服务方法的结果中显示异常,这很好,因为这意味着我至少可以在客户端显示某些内容,但我还想在此之前捕获它,以便我可以处理不同的异常服务器-侧.

到目前为止,我唯一一致的方法是将每个单独的方法包装在一个try..except块中,并在重新引发异常之前处理每个方法中的异常.但是,随着20种方法的Web服务不断增长,这种情况并没有真正扩大.

我也尝试过实现一些Datasnap组件的OnError,OnTrace和其他事件(TDSServer,TDSHTTPService,TDSTCPServerTransport等),但这些事件似乎也从未被解雇过.

有没有人遇到这样的事,拜托?

Lud*_*ehm 0

Tl;Dr: it's not implemented in a usable fashion (in 10.1 Berlin).

I came across the same problem and after reading through a lot of source, I found no practical solution.

So an exemplary (my) StackTrace would look like this:

MyClass::MyServerMethod()
/* skipping some funny unimportant RTTI/TValue handling here */
System::Rtti::TRttiMethod::Invoke
Dsreflect::TDSMethod::Invoke(TObject, TDSMethodValues)
TDSServerConnectionHandler::DbxExecute(const TDBXExecuteMessage)
TDSServerCommand::DerivedExecuteUpdate
TExecuteCallback
TDSService::Execute(const string, const TRequestCommandHandler, TExecuteCallback)
TDSService::ProcessRequest(const string, const TRequestCommandHandler, TExecuteCallback)
TDSRESTService::ProcessREST(const string, const string, const TArray<Byte>, const TRequestCommandHandler)
TDSRESTService::ProcessGETRequest(const string, TStrings, TArray<Byte>, TRequestCommandHandler)
TDSRESTServer::DoDSRESTCommand(TDSHTTPRequest, TDSHTTPResponse, string)
TDSRESTServer::DoCommand(TDSHTTPContext, TDSHTTPRequest, TDSHTTPResponse)
Dshttpwebbroker::TDSRESTWebDispatcher::DispatchRequest(TObject, Web::Httpapp::TWebRequest, Web::Httpapp::TWebResponse)
Run Code Online (Sandbox Code Playgroud)

Note: This depends entirely on your usage of DataSnap. In the above case requests are passed into the DataSnap API through TDSRESTWebDispatcher (comming from TIdCustomHTTPServer).

  • Every Exception raised in a ServerMethod will end up in TDSService::ProcessRequest.
  • In this procedure every Exception is caught and ONLY its Message is added to a TRequestCommandHandler->CommandList.
  • Further down the Message is written as JSON/DBX command to the output.

So we can never handle the Exception Object and access the StackTrace or other information. So this alone is unacceptable and has to change

The good news is, that this procedure is virtual and can be overwritten. The bad news is, that in the example above you would have to extend TDSRESTService with your own ProcessRequest procedure (including your errorhandler), TDSRESTServer with own DoDSRESTCommand (in there the TDSRESTService is created in a monstrously large procedure) and TDSRESTWebDispatcher (depending on your usage).

My personal recommendation is to don't use DataSnap.

Note: At the point of writing this, I haven't found any invoke of the OnError event.