2014-03-26 36 views
0

我在Delphi XE中創建了一個try/except/finally語句,當應用程序生成異常時,except塊永遠不會被稱爲直接跳轉到finally塊,我嘗試了一些東西,如反轉try/except/finally以嘗試/ finally/except,嘗試將try塊更改爲不同的地方,清理代碼並重新編譯以防萬一是Delphi問題,但注意到似乎工作正常。嘗試/除外/最後在Delphi中不能正常工作XE

我在這裏試圖完成的是向用戶顯示一個對話框消息,並在發生崩潰時清理代碼。

procedure CallbackExport(Sender: TObject); 
var 
    SaveDlg: TSaveDialog; 
    FileName: string; 
begin 
    SaveDlg := TSaveDialog.Create (nil); 
    try 
    try 
     SaveDlg.Title := 'Export'; 
     SaveDlg.InitialDir := GetSystemPath(CSIDL_DESKTOP); 
     SaveDlg.Options := [ofOverwritePrompt, ofEnableSizing]; 

     case (Sender as TMenuItem).Tag of 
     cnExcel: begin 
      SaveDlg.Filter := 'Excel File (*.xls)|*.xls'; 
     end; 
     cnHtml: begin 
      SaveDlg.Filter := 'HTML File (*.html)|*.html'; 
     end; 
     cnTxt: begin 
      SaveDlg.Filter := 'Text File (*.txt)|*.txt'; 
     end; 
     cnCsv: begin 
      SaveDlg.Filter := 'Comma Seperated File (*.csv)'; 
     end; 
     cnXml: begin 
      SaveDlg.Filter := 'XML file (*.xml)|*.xml'; 
     end; 
     end; 
     if not SaveDlg.Execute(self.Handle) then 
     Exit; 
     FileName := SaveDlg.FileName; 

     case (Sender as TMenuItem).Tag of 
     cnExcel: begin 
      ExportGridToExcel(FileName, tvdGrid); 
     end; 
     cnHtml: begin 
      ExportGridToHTML(FileName, tvdGrid); 
     end; 
     cnTxt: begin 
      ExportGridToText(FileName, tvdGrid); 
     end; 
     cnCsv: begin 
      ExportGridToText(FileName, tvdGrid, true, true, ',', '', '', 'CSV'); 
     end; 
     cnXml: begin 
      ExportGridToXML(FileName, tvdGrid); 
     end; 
     end; 
    except 
     on e: exception do 
     begin 
     ShowMessage('An error occurred while saving the file ' + FileName + #13#10 + 'With a message: ' + E.Message); 
     StvdAudit.tvdAudit('Error saving file, reason: ' + E.Message); 
     end; 
    end; 
    finally 
    SaveDlg.Free; 
    end; 
end 
+1

這段代碼看起來像它應該工作。你能提供一個我們可以實際編譯和測試的可重複的例子嗎? –

+3

您如何知道正在生成異常?嘗試明確地引發異常,看看會發生什麼。放「引發異常。create('這是個例外');」在第二次TRY之後。 –

+0

我同意。正如所示,這段代碼很少會引發異常。 –

回答

6

如果拋出一個異常在try內部/除,而不是通過代碼進一步下跌的調用堆棧處理,將您的異常處理程序捕獲。

您聲稱ExportGridToXXX正在引發您的代碼中未被異常處理程序捕獲的異常。但是這種說法不可能是真的。要麼沒有例外,否則ExportGridToXXX已經處理了異常。

關於異常處理這個更普遍的問題,一般的政策應該是儘可能不處理它們。只有當您需要停止異常傳播時才應該處理它們,並且需要在代碼中處理異常。通常,特別是在UI程序中,您只需讓頂級異常處理程序處理異常即可。

就像這一點一樣,你編碼吞下所有的異常,而不管它們的類型如何。這是不好的做法。假設您確實想要處理由ExportGridToXXX引發的異常,則只應處理預期的異常類。例如,您可能會遇到EAccessViolation,您的應用的政策將終止。但是,既然你吞下了它,用同樣的處理器來對待它,以防止共享違規,你就不能應用這個策略。在處理例外時總是要看清楚。

0

Export(smth)函數是否駐留在單獨的DLL中?然後你的應用程序的Exception類與外部DLL的Exception類不一樣。

0

您的異常處理程序被吞嚥異常,請嘗試重新提升,而不是:

on e: exception do 
begin 
    StvdAudit.tvdAudit('Error saving file, reason: ' + E.Message); 
    raise exception.create('An error occurred while saving the file ' + FileName + #13#10 +  'With a message: ' + E.Message); 
end;