尝试/除外/最后在Delphi XE中无法正常工作

时间:2014-03-26 00:02:02

标签: delphi exception-handling try-catch delphi-xe

我在Delphi XE中遇到这个有趣的问题,我在其中创建了一个try / except / finally语句,当应用程序生成异常时,except块从不被调用,它直接跳转到finally块,我尝试了几件事比如将try / except / finally反转为try / finally / except,尝试将try块更改为不同的位置,清理代码并重新编译以防万一是Delphi问题,但注意似乎有效。

我在这里尝试完成的是向用户显示一条对话框消息,并在发生崩溃后清理代码。

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

3 个答案:

答案 0 :(得分:7)

如果在try / except中引发异常,并且没有被调用堆栈中的代码处理,则它将被异常处理程序捕获。

您声称ExportGridToXXX正在引发代码中未被异常处理程序捕获的异常。但这种说法不可能是真的。要么没有引发异常,要么ExportGridToXXX已经处理了异常。

关于异常处理的更一般主题,一般政策应该是尽可能不处理它们。您应该只在需要停止异常传播的情况下处理它们,并且需要在代码中此处处理异常。通常,特别是在UI程序中,您只需让顶级异常处理程序处理异常。

除此之外,您编写代码会吞下所有异常,无论其类型如何。这是不好的做法。假设您确实想要处理ExportGridToXXX引发的异常,那么您应该只处理预期的异常类。例如,您可能会遇到应用程序的策略要终止的EAccessViolation。但是,由于您吞下它,在用于捕获共享冲突的相同处理程序中处理它,您无法应用该策略。在处理异常时始终要清楚。

答案 1 :(得分:0)

Export(smth)函数是否驻留在单独的DLL中?然后,您的应用程序的Exception类与外部DLL的Exception类不同。

答案 2 :(得分: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;