I know it sounds like an old stupid question but I searched all over the internet and I still don't understand one thing. I understand that try-finally will run the finally code before stopping for error (or don't stopping when no exceptioned was raised) and that try-except will run the except code when exception is raised. But what I still don't understand is the point of try-except within try-finally statements. I'll write an example
What I always do is something like this:
a:=x.Create;
try
a.DoRiskyStuff;
except
ShowMessage('Error!');
end;
a.free;
I have never in a years used a finally clause because I always handle the errors and I never understood what is the point to use them both nested together. What's bad about my solution? Why in examples it's common to use something like this:
a:=x.Create;
try
try
a.DoRiskyStuff;
except
ShowMessage('Error!');
end;
finally
a.free;
end;
What's the difference? Why should somebody use a finally clause when all cleanup can be done after the try-except?
Thank you very much for any asnwers!
Edit: I changed the create lines so some of you want bash me for it ;)
The try block lets you test a block of code for errors. The except block lets you handle the error. The else block lets you execute code when there is no error. The finally block lets you execute code, regardless of the result of the try- and except blocks.
finally is usually used to close a code properly after its encountered an Exception or Error. This means that no matter whether an exception/error comes or not, 1nce the try/try-catch block ends, the finally block WILL be executed. Answer: finally block always executes whether the exception has occured or not.
There are two big differences between those two constructs. A technical one and a semantical one.
Technically, the difference is that the finally
block will always be executed, even if there is no exception, while the except
block is only executed when there is an exception.
The finally
block is even executed when you exit the function early using Exit
in a try-finally
block.
Additionally, the finally
block does not swallow the exception, while the except
block generally swallows it, and it can only escape the block if the type of exception does not match the exception types you specify in on ... do
, or if you manually re-raise
it.
The except
block is meant to handle the exception(s), while the finally
block is not. The finally
block is meant to contain code that should be executed regardless of an exception, i.e. mainly to protect resources. That is why you should do:
X := TY.Create;
try
// Code that may raise an exception.
finally
X.Free; // Free resource, even if there was an exception.
// Exception is NOT handled.
end;
and:
try
// Code that may raise an exception.
except
// Handle the kind of exceptions you can handle.
end;
Note that resource protection with finally
is not limited to memory and Free
. You can restore/undo/close anything that should be restored/undone/closed, i.e. close opened files, close open connections, shut down hardware that was started, restore mouse pointers to their previous form, etc.etc.
So you can also use it for code like:
Cursor := crMultiDrag;
try
// Code that may raise exception.
finally
Cursor := crDefault;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With