2015-12-01 32 views
5

私のDatasnap RESTサービス(Delphi XE3ではなく、Delphi 10 Seattleでも試していました)の中で例外処理に苦労しています。私は何年にもわたって6つのWindowsサービスを作成しており、Windowsイベントログにアプリケーション例外をすべて記録できるように、常にTApplicationEventsコンポーネントが含まれています。Delphiでの例外処理Datasnap RESTサーバ

ただし、この動作はDatasnapサービスでは発生していません。 TApplicationEvents.OnExceptionイベントは一度も発生しませんので、ここに来る前に何か他のものが例外を食べていると想定して処理しています。

例外はWebサービスメソッドの結果に表示されます。これは、少なくともクライアント側で何かを表示できるという意味でありますが、その前にキャッチすることもできますサーバー側で異なる例外を処理します。

これまで管理してきた唯一の一貫した方法は、try..exceptブロックに個々のメソッドをラップし、例外を再発生させる前に各メソッドで例外を処理することです。しかし、20のメソッドと成長のWebサービスでは、これは実際にスケールアップするつもりはありません。

また、私はOnError、OnTraceなどのDatasnapコンポーネント(TDSServer、TDSHTTPService、TDSTCPServerTransportなど)の一部のイベントを実装しようとしましたが、これらは決して解雇されないようです。

誰もこのようなことを知っていますか?

+0

関連(Java用):[JavaサーブレットWebアプリケーションで捕捉されない例外を取得する方法](http://stackoverflow.com/questions/7410414/how-to-grab-uncaught-exceptions-in-a-java -servlet-web-application)同様の解決策が可能かもしれません。 (Datasnapにグローバルリクエストフィルタメカニズムがある場合) – mjn

答えて

0

Tl; Dr:使用可能な方法で実装されていません(ベルリン10.1)。

私は同じ問題を遭遇し、多くの情報源から読んだ後、実用的な解決策は見つけられませんでした。

だから、模範的な(私の)スタックトレースに次のようになります。

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) 

注:これは、DataSnapのの使用状況に完全に依存。上記の場合、リクエストはTDSRESTWebDispatcherTIdCustomHTTPServer)からDataSnap APIに渡されます。 ServerMethodで育っ

  • すべてExceptionTDSService::ProcessRequestになってしまいます。
  • この手順では、すべてExceptionがキャッチされ、そのMessageTRequestCommandHandler->CommandListに追加されます。
  • さらに下へMessageはJSON/DBXコマンドとして出力に書き込まれます。

だから我々はExceptionオブジェクトを処理していないとStackTraceまたは他の情報にアクセスすることができません。したがって、これだけでは受け入れられず、変更する必要があります

良いニュースは、この手順はvirtualであり、上書きできるということです。悪いニュースは、あなたの上記の例ではそれは、(あなたのErrorHandlerを含む)、独自のProcessRequest手順で自分のDoDSRESTCommandTDSRESTServer(そこにTDSRESTServiceがものすごい大の手順で作成された)とTDSRESTWebDispatcherTDSRESTServiceを延長しなければならない、である(に応じて、お使いの使用法)。

個人的には、DataSnapを使用しないことをお勧めします。

注:これを書いている時点で、OnErrorイベントの呼び出しは見つかりませんでした。