Try Catch Finally Question

try catch finally question

Not only will a finally block execute following a catch block, try does not even require that any exception be caught for the finally to execute. The following is perfectly legal code:

try 
{
//do stuff
}
finally
{
//clean up
}

I actually took out the catch blocks in some code I inherited when the catch block consisted of:

catch(Exception ex)
{
throw ex;
}

In that case, all that was required was to clean up, so I left it with just a try{} and finally{} block and let exceptions bubble up with their stack trace intact.

What is the purpose of finally in try/catch/finally

In your example, it doesn't make a whole lot of difference.

Picture this, though:

    try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (SomeOtherException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
finally
{
Console.WriteLine("Executing finally block.");
}

Console.WriteLine("Executing stuff after try/catch/finally.");

In this case, the catch won't catch the error, so anything after the whole try/catch/finally will never be reached. However, the finally block will still run.

Exception Handling in c# - try catch finally

In really simple terms, these are what try-catch-finally blocks do:

Try

The place where you'd put potentially problematic code. If an exception is generated, an exception will be thrown.

Catch

Catch is the ONLY block where an exception will be caught. Hence the name. So when an exception is thrown, if you want to ensure the program doesn't 'hang', you must catch the exception.

Finally

Do your cleanup. If, say, you have some array in your try block and you want to clean it up in case of an exception, this is the place to do it.

Try-Finally

The documentation says:

Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.

Meaning, if you don't catch your exception, it depends on the situation whether finally is run.

So, with that in mind, let's look at your first code block.

static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}

You're attempting to do a divide by zero which generates an exception. But there's no place for it to be 'caught', so the program hangs:

enter image description here

So if you add a catch block here, now it will allow for smooth sailing and go to your finally as well.

try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine("Oops. Division by Zero.");
}
finally
{
Console.WriteLine("I am finally block");
}

Now let's take your second code snippet. I'm going to do a small modification and flip the order of two lines of code inside the catch.

static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}

Now, the catch block catches the exception thrown by the first illegal division and prints a message. But then there's a second illegal division inside the catch, and there's no catch for that thrown exception so the program hangs.

So if you modify it to have a second try-catch inside the first catch like so:

static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
try
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
catch (Exception ex2)
{
Console.WriteLine(ex2.Message);
}
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}

Now it will catch both exceptions and you're good to go.

So the idea is, if you have a try you should try to have a catch unless you can justify why you don't want one.

Can I use try-catch-finally like this?

Finally will always be executed, so in this case, it is not its intended purpose, since normal execution would reopen the file a second time. What you intend to do would be achieved in the same (cleaner) way if you do

$s = "";

$c = MyClassForFileHandling::getInstance();

try
{
$s = $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
$s = $c->get_file_content($path);
}

Then the manual says:

For the benefit of someone anyone who hasn't come across finally blocks before, the key difference between them and normal code following a try/catch block is that they will be executed even the try/catch block would return control to the calling function.

It might do this if:

  • code if your try block contains an exception type that you don't catch
  • you throw another exception in your catch block
  • your try or catch block calls return

Finally would then be useful in this kind of scenario:

function my_get_file_content($path)
{
try
{
return $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
return $c->get_file_content($path);
}
finally
{
$c->close_file_handler();
}
}

=> if you need to make sure you close your file handler in this case, or some resource in general.

The order of return value with try catch finally

This question is closely related, although it returns literals but not variables: Multiple returns: Which one sets the final return value?

In fun1 the return value is set via return a in the catch-block. At that line the value of a is copied into the return value. Changing a later does not change the return value.

In fun2 you have an explicit return in the finally block, so the return value in the finally block is what is returned.

Please read carefully through the answers in the question above for why you should not write code like that.

Another related question is this one: Returning from a finally block in Java



Related Topics



Leave a reply



Submit