Unfortunately, the "old-style" DataSnap server exceptions are marshalled to the client as text only (E.Message) so the exception class name and instance data are lost in the process. See SConnect
unit, TDataBlockInterpreter.InterpretData
method (the except block).
EDIT: Here's a very simplistic example to give you an idea (not tested at all):
// 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;