Tidbits

Finally is no catch-all

This is just a short “nice to know” for C# exception handling, that i only learned about after half an hour of frustrated debugging.


Imagine some code which changes persistent data. Might be files, a database or some OS settings. Just something that stays even after your program closes.
Now imagine you have to change this data to make an important operation, but have to change it back after you’re done so you won’t mess up something else.

SetSystemValue();
DoWork();
ResetSystemValue();

What if something unexpected happens in DoWork?
The changes we made won’t be changed back. Can’t have that.
So, we do what we learned is the proper way of dealing with the unexpected:

try
{
    SetSystemValue();
    DoWork();
}
finally
{
    ResetSystemValue();
}

Now, no matter what happens in the try block, the changes we’ve made are going to be reversed.


Only, there is a condition to finally you usually don’t need to think about:
It isn’t executed until after catch.
And when there is no catch, the program just terminates.

See the problem?
Usually there will be a catch somewhere up the chain to handle the exception.
And if there isn’t and the program terminates, we don’t have to worry about some invalid data in our program anyway.

In this case however, the data exists outside the program, meaning any issues persist with it.


Solution:
Add a catch somewhere. Specifically a catch that doesn’t (re-)throw an exception. Having a try/catch at your programs root for logging might be useful anyway.
Of course, if you already have a try/finally, why not simply add a catch in there as well?
In my case I simply doubled down on the reset part (to avoid calling it twice), which now looks somewhat like this:

try
{
    SetSystemValue();
    DoWork();
}
catch
{
    ResetSystemValue();
    return;
}
 
ResetSystemValue();