I have the following code:
SqlConnection ret = new SqlConnection(connectionString);
This throws a ConfigurationException
which I catch, however, since the exception occurs in the constructor itself, the ret
is null/unassigned, so I am not able to call Dispose/Close
on the new instance of SqlConnection
.
As a result, at some random time in the future, the Finalize
method of the created (but unassigned to the ret
variable) SqlConnection
instance gets called (most likely from a separate thread) which throws the same ConfigurationException
but I am not able to catch it since it occurs on a different thread. This brings the whole app down.
What is the correct coding approach to handle this situation?
P.S. The exception is because of an unexpected section in the machine.config
file, but we need to handle it via code instead of asking customers to fix the machine.config
file.
I think it's reasonable for an issue in the machine.config
file to mean that an app simply can't run. If your system-wide configuration is broken, you (the owner of that broken configuration) should fix it. Not all failures can be properly handled in code.
I would recommend not trying to work around this, but to detect it early on, and abort in as clean a way as possible. If you're aware that this can be an issue, you might want to explicitly check for it - in as error-free a way as you can find - immediately on startup, and fail with a really good error message and advice. As a user, I would generally far rather something failed early with clear steps for fixing the issue than trying to limp on regardless, but doing a poor job due to being in a fundamentally hostile environment.
You should also report the issue to Microsoft, as the SqlConnection
finalizer throwing an exception when the constructor didn't even complete is very nasty.