首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在TDatasetProvider.OnUpdateError中引发时无法识别EUpdateError异常。为什么?

在TDatasetProvider.OnUpdateError中引发时无法识别EUpdateError异常。为什么?
EN

Stack Overflow用户
提问于 2010-05-26 18:07:42
回答 1查看 564关注 0票数 0

当我在TDatasetProvider.OnUpdateError事件中重新抛出一个EUpdateError异常时,它在catch块中没有被识别为EUpdateError异常。它只被识别为基本Excption

代码语言:javascript
复制
try
  ...
  //calls the TDatasetPorvider.OnUpdateError event.
  myClientDataSet.ApplyUpdates(0);
  ...
except
 on ex: EUpdateError do
 begin
   //never goes here
   //Evaluate ex.ErrorCode
 end;
 on ex: Exception do
 begin
   //always goes here
   //the expression (ex is EUpdateError) returns false;
 end;
end;

下面是相应的.OnUpdateError实现:

代码语言:javascript
复制
procedure MyDataModule.MyDatasetProviderOnUpdateError(..;E: EUpdateError;...);
beign
  //Here, the expression (E is EUpdateException) returns true;
  raise E;
end;

异常被重新抛出,但是看起来EUpdateError被转换成了一个简单的基本Exection.

有人知道为什么类类型迷失了方向吗?

我需要该类型,以便检查.ErrorCode,了解哪里出了问题,并准备适当的用户消息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-05-26 21:25:21

不幸的是,“旧式”DataSnap服务器异常是作为纯文本(E.Message)编组到客户端的,因此异常类名和实例数据会在此过程中丢失。请参见SConnect单元、TDataBlockInterpreter.InterpretData方法( except块)。

编辑:这里是一个非常简单的例子,给你一个想法(根本没有测试):

代码语言:javascript
复制
// 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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2911921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档