不幸的是,「舊式」 DataSnap服務器異常編組到客戶端爲純文本(E.Message)所以異常類名和實例數據的過程中丟失。見SConnect
單位,TDataBlockInterpreter.InterpretData
方法(除塊)。
編輯:這是一個非常簡單的例子給你一個想法(在所有未測試):
// new methods
function TDataBlockInterpreter.ReadException(const Data: IDataBlock): Exception;
var
Flags: TVarFlags;
AClassName, AMessage, AContext: string;
ErrorCode, PreviousError: Integer;
OriginalException: Exception;
begin
AClassName := ReadVariant(Flags, Data);
AMessage := ReadVariant(Flags, Data);
if AClassName = 'EUpdateError' then
begin
AContext := ReadVariant(Flags, Data);
ErrorCode := ReadVariant(Flags, Data);
PreviousError := ReadVariant(Flags, Data);
OriginalException := ReadException(Data);
Result := EUpdateError.Create(AMessage, AContext, ErrorCode, PreviousError, OriginalException);
end
// else if AClassName = ... then ...
else
Result := Exception.Create(AMessage);
end;
procedure TDataBlockInterpreter.WriteException(E: Exception; const Data: IDataBlock);
begin
WriteVariant(E.ClassName, Data);
WriteVariant(E.Message, Data);
if E is EUpdateError then
begin
WriteVariant(EUpdateError(E).Context, Data);
WriteVariant(EUpdateError(E).ErrorCode, Data);
WriteVariant(EUpdateError(E).PreviousError, Data);
WriteException(EUpdateError(E).OriginalException, Data);
end;
end;
// modified methods
procedure TDataBlockInterpreter.DoException(const Data: IDataBlock);
begin
raise ReadException(Data);
end;
procedure TDataBlockInterpreter.InterpretData(const Data: IDataBlock);
var
Action: Integer;
begin
Action := Data.Signature;
if (Action and asMask) = asError then DoException(Data);
try
case (Action and asMask) of
asInvoke: DoInvoke(Data);
asGetID: DoGetIDsOfNames(Data);
asCreateObject: DoCreateObject(Data);
asFreeObject: DoFreeObject(Data);
asGetServers: DoGetServerList(Data);
asGetAppServers: DoGetAppServerList(Data);
else
if not DoCustomAction(Action and asMask, Data) then
raise EInterpreterError.CreateResFmt(@SInvalidAction, [Action and asMask]);
end;
except
on E: Exception do
begin
Data.Clear;
Data.Signature := ResultSig or asError;
WriteException(E, Data);
FSendDataBlock.Send(Data, False);
end;
end;
end;
有沒有辦法到(SQL /數據庫)錯誤代碼發送到try-except塊,爲了區分錯誤信息(爲了對錯誤代碼做出決定)? – 2010-05-29 07:06:34
是的,但您必須修改和重建服務器和客戶端可執行文件。您可以包含類名並使用一些實用程序函數來傳輸特定的異常實例數據,如SQL錯誤代碼。 – 2010-05-29 12:48:38
實際上,我沒有獨立的服務器客戶端應用程序。 TDataSetProvider和TClientDataSet組件位於同一個DataModule中(它是單個可執行文件)。 – 2010-05-29 12:53:40