3

A comment by a high rep user on another question I asked earlier today suggested it would be better to swap the order of try/finally and try/except.

So, instead of this:

try
  try
    //some code
    //something that throws an exception, eg: EIndexOutOfRangeException 
    //more code
  except on E : EIndexOutOfRangeException do begin .... end;
finally
  // some cleanup code
end;

it would have the try/finally nested inside and the try/except on the outside:

try
  try
    //some code
    //something that throws an exception, eg: EIndexOutOfRangeException 
    //more code
  finally
    // some cleanup code
  end;
except on E : EIndexOutOfRangeException do begin .... end;
end;

I would like to know when is it appropriate and a good idea to use this idiom, and are there exceptional cases where you shouldn't? Why prefer one over the other? I suppose exceptions being thrown in the cleanup code would be the main consideration, since I imagine it could suppress one of the exceptions if finally throws an exception, but could prevent unexpected bubbling up of errors?

Community
  • 1
  • 1
Jessica Brown
  • 8,222
  • 7
  • 46
  • 82

1 Answers1

6

You can use both the ways of writing try,catch and finally and it varies from situation to situation.

Consider the following code listing for try...except inside try...finally.

//You will receive a DataSet is some state.
try   
   try
      //Here you'll change its state and perform operations on it.
      //If some exception occurred you will handle it.
   except
      //Handle exception.
   end;  
finally
 //Put the DataSet again in the same state.
end;

The above code listing shows the uses of try...except inside a try...finally block.

Consider the following code listing for try...finally inside try...except.

try  
   LObject:= TObject.Create;
   //Create an Object. It better idea to create an object outside try..finally block.
   //If some exception occured while creating an object an exception will be thrown.
   //However its not a good idea to catch such an exception.Let the system handle it.
   try
      //Use the Object. 
   finally
      //Free Object.
   end;  
  // Returns True
except
  // Returns False.
end;

Here the above code listing may be used in such a situation where the function return only true and false. If some exception occurred then simply set the value to false.

Rahul Sharma
  • 347
  • 1
  • 16
  • 4
    The comment in the second example says `Let the system handle it.` but why is the exception swallowed in the try .. except then? – mjn Jul 09 '14 at 06:43
  • What I was trying to say, that if some exception occurred while creating an object, let say that there is no enough memory to allocate to that object in such situation we should let the system handle it, however such situation is very rare. Please enlighten if I am wrong somewhere. – Rahul Sharma Jul 09 '14 at 06:54
  • 2
    I believe the confusing bit @mjn is referring to is that your comment says "Let the system handle it" but the code that follows *does not let the system handle it*, because you've got an except block there that would catch anything thrown by `TObject.Create`. – Andriy M Jul 09 '14 at 07:34
  • @Andriy exactly, the code does what the comment says, so one of them must be wrong – mjn Jul 09 '14 at 08:30
  • I read the comment and code as "handle exceptions of interest, raise all others". It's uncommon to unconditionally swallow all exceptions isn't? – Shannon Matthews Jul 10 '14 at 22:38