Question

I'm having this funny issue with Delphi XE where I create a try/except/finally statement and when the application generate an exception the except block is never called it jump straight to the finally block, I tried few things like invert the try/except/finally to try/finally/except, try to change the try blocks to different places, clean the code and recompile in case was a Delphi issue but noting seems to work.

What I'm trying to accomplish here is to show a dialog message to the user and after clean up the code in case of a crash.

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
Was it helpful?

Solution

If an exception is raised inside the try/except, and not handled by code further down the call stack, it will be caught by your exception handler.

You are claiming the ExportGridToXXX is raising an exception that is not caught by the exception handler in your code. But that claim cannot be true. Either no exception is raised, or ExportGridToXXX already handles the exception.

On the more general subject of exception handling, the general policy should be not to handle them if at all possible. You should only handle them in case you need to stop the exception propagating, and need to deal with the exception at this point in the code. Normally, particularly in a UI program, you would simply let the exception be handled by the top-level exception handler.

As well as that point, you code swallows all exceptions, irrespective of their type. That's bad practice. Supposing that you do want to handle exceptions raised by ExportGridToXXX, you should only handle the exception classes that are expected. For instance, you might encounter EAccessViolation for which your app's policy is to terminate. But since you swallowed it, treating it in the same handler used to trap sharing violations, you cannot apply that policy. Always be discerning in your handling of exceptions.

OTHER TIPS

Do the Export(smth) functions reside in a separate DLL? Then your application's Exception class is not the same as external DLL's Exception class.

Your exception handler is swallowing the exception, try re-raising instead:

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top