Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will Try / Finally (without the Catch) bubble the exception?

People also ask

Can we have try finally without catch?

Yes, It is possible to have a try block without a catch block by using a final block. As we know, a final block will always execute even there is an exception occurred in a try block, except System. exit() it will execute always.

What happens if exception is not caught in try catch?

If an exception is not caught (with a catch block), the runtime system will abort the program (i.e. crash) and an exception message will print to the console. The message typically includes: name of exception type.

Does finally handle exception?

The finally block executes whether exception rise or not and whether exception handled or not. A finally contains all the crucial statements regardless of the exception occurs or not. In this case, the program runs fine without throwing any exception and finally block execute after the try block.

How do you handle exceptions with try finally?

Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try - finally statement.


Yes, it absolutely will. Assuming your finally block doesn't throw an exception, of course, in which case that will effectively "replace" the one that was originally thrown.


Any thoughts on the practice in general?

Yes. Be careful. When your finally block is running, it is entirely possible that it is running because an unhandled, unexpected exception has been thrown. That means that something is broken, and something completely unexpected could be happening.

In that situation it is arguably the case that you shouldn't run code in finally blocks at all. The code in the finally block might be built to assume that subsystems it depends upon are healthy, when in fact they could be deeply broken. The code in the finally block could make things worse.

For example, I often see this sort of thing:

DisableAccessToTheResource();
try
{
    DoSomethingToTheResource();
}
finally
{
    EnableAccessToTheResource();
}

The author of this code is thinking "I am making a temporary mutation to the state of the world; I need to restore the state to what it was before I was called". But let's think about all the ways this could go wrong.

First, access to the resource could already be disabled by the caller; in that case, this code re-enables it, possibly prematurely.

Second, if DoSomethingToTheResource throws an exception, is the right thing to do to enable access to the resource??? The code that manages the resource is unexpectedly broken. This code says, in effect "if the management code is broken, make sure that other code can call that broken code as soon as possible, so that it can fail horribly too." This seems like a bad idea.

Third, if DoSomethingToTheResource throws an exception, then how do we know that EnableAccessToTheResource will not also throw an exception? Whatever awfulness befell the use of the resource might also affect the cleanup code, in which case the original exception will be lost and the problem will be harder to diagnose.

I tend to write code like this without using try-finally blocks:

bool wasDisabled = IsAccessDisabled();
if (!wasDisabled)
    DisableAccessToTheResource();
DoSomethingToTheResource();
if (!wasDisabled)
    EnableAccessToTheResource();

Now the state is not mutated unless it needs to be. Now the caller's state is not messed around with. And now, if DoSomethingToTheResource fails, then we do not re-enable access. We assume that something is deeply broken and do not risk making the situation worse by trying to keep running code. Let the caller deal with the problem, if they can.

So when is it a good idea to run a finally block? First, when the exception is expected. For example, you might expect that an attempt to lock a file might fail, because someone else has it locked. In that case it makes sense to catch the exception and report it to the user. In that case the uncertainty about what is broken is reduced; you are unlikely to make things worse by cleaning up.

Second, when the resource you are cleaning up is a scarce system resource. For example, it makes sense to close a file handle in a finally block. (A "using" is of course just another way of writing a try-finally block.) The contents of the file might be corrupt, but there's nothing you can do about that now. The file handle is going to be closed eventually, so it might as well be sooner rather than later.