天天看點

捕獲ClientDataSet.ApplyUpdates和SocketConnection異常

核心提示:如何捕獲ClientDataSet.ApplyUpdates的錯誤,不用ReconcileError...

var
  cdsEmp:TClientDataSet;
//儲存
procedure  TfrmEmp.btnSave(Sender:  TObject);
begin
  cdsEmp.RemoteServer.AppServer.BegTrans;
  try
    cdsEmp.ApplyUpdates(0);  //更新錯誤在這一句發生,但是我卻永遠也捕獲不到,
                             //我想自已在異常處理裡顯示這裡發生的錯誤資訊該怎麼辦?
    cdsQrObj.RemoteServer.AppServer.ComTrans;
  except
    on  E:Exception  do
    begin
      cdsEmp.RemoteServer.AppServer.RobTrans;
      Application.MessageBox(pchar('存盤失敗!'+#13#10+'錯誤資訊:'+E.Message),'提示',MB_OK+MB_ICONEXCLAMATION);
      Abort;
    end;
  end;
end;
//如果用這個錯誤處理,我的事務復原卻不知放在何處才妙,并且我不是想用這個錯誤處理
procedure  TfrmEmp.cdsEmpReconcileError(
   DataSet:  TCustomClientDataSet;  E:  EReconcileError;
   UpdateKind:  TUpdateKind;  var  Action:  TReconcileAction);
begin
   HandleReconcileError(DataSet,  UpdateKind,  E);
   Action:=raAbort;
end;
解答一:
//---------------------------------------------------------------
//據我所知,隻能用ReconcileError 可以用下面的方法判斷是否錯誤
...
BeginTransaction;
if cdsMaster.ApplyUpdates(0)+cdsDetail.ApplyUpdates(0)=0  then
  CommitTransaction
else
  RollbackTransaction;
ApplyUpdates方法傳回更新時遇到的錯誤數量.
...
//---------------------------------------------------------------
 
解答二:
//---------------------------------------------------------------
在DataSetProvider的onUpdateError
raise  E;
然後就可以在用戶端的
try
  ClientDataSet1.ApplyUpdates(0);
except
  on  e:Exception  do
  ...
end;
//----------------------------------------------------------------
解答三:
    其實真正的捕獲ClientDataSet.ApplyUpdate異常的方法應該是在Apllication的異常中捕獲并處理它。因為ClientDataSet抛出的異常為線程(程序?)異常,在ClientDataSet的ApplyUpdate中用try...except...end;是無法捕獲的。
    具體方法為:在公共單元如DataModule中放置一個ApplicationEvent件,在該控件的OnException事件中捕獲異常,該窗體應在所有有可能産生ApplyUpdate或Connection異常的窗體之前建立。
procedure TClient_RDataForm.ApplicationEvents1Exception(Sender: TObject;
  E: Exception);
begin
  if (E is ESocketConnectionError) or (E is ESocketError) then
  begin
    if not Is_OK then
    begin
      Application.MessageBox(PChar('考試應用伺服器或網絡連接配接失敗!請退出後重新啟動考試系統!  '),
                      '伺服器連接配接中斷', MB_OK + MB_ICONERROR);
      Application.Terminate;
      Exit;
    end;
    while not ReConnect_Srv do //重新連接配接又失敗了
    begin
      if Application.MessageBox(PChar('考試伺服器或網絡連接配接失敗!請立即與監考老師聯系!  '+#13+'要重新搜尋伺服器請按[是],強制退出請按[否]!  '),
                      '伺服器連接配接失敗', MB_YESNO + MB_ICONSTOP) <> IDYES then
        if (Application.MessageBox('真的要強制退出考試系統嗎?  ','強制退出确認', MB_YESNO + MB_ICONWARNING + MB_DEFBUTTON2) = IDYES) then
        begin
           Application.Terminate;
           Exit;
        end;
    end;
    if MyConnection.Connected then
    begin
      Application.MessageBox('考試應用伺服器恢複連接配接成功!','連接配接成功',MB_OK+MB_ICONINFORMATION);
      Exit;
    end;
  end else
    raise Exception.Create('考試系統發生異常錯誤!退出後請重新啟動考試系統繼續考試!');
    //ShowMessage(e.Message);
end;      

繼續閱讀