6

I have a function that looks like this:

try
{
     _dbManager.InsertSearch(some data);
}
catch (Exception ex)
{
    //do logging
}

_dbManager uses LINQ to insert data to a SQL database. Yesterday, the machine that hosts the database ran out of hard disk space and my program crashed. I got a crash dump which shows that there was a SqlClient.SqlException raised with an exception message reading something like "Database transaction log is full...".

My question is: Why didn't the exception get caught in the catch block above? The weird thing is, when I tried to reproduce the issue, I could get the same exception, but it was caught by the catch block. What could be the issue?

Second, related question: Imagine if we use a third party library and we don't want any exception thrown. We can use try-catch block, but this only works on calling thread. What if the third party starts new thread and an exception is thrown there? Is there a way to handle this? I know I can register our UnhandledExceptionHandler, but that seems to be a different from what I wanted.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
ColdEar
  • 71
  • 4
  • 2
    Was the logging in the catch statemnt being logged to the server that had run out of disk space, by any chance? Do you have a backup method of logging an error within the logging mechanism? For example, our general practice is to use a nested structure to try to log first to our global error handling database, then to the event log, then to an email. – David Sep 24 '11 at 16:26
  • the logging part wasn't reached at all when crash occurred. it crashed inside _dbManager.InsertSearch(). btw, we do use MSEL logging application block, and configured it to log using different method. – ColdEar Sep 24 '11 at 16:34
  • and none of the method will log to that sql server machine – ColdEar Sep 24 '11 at 16:38
  • Kinda pointless to not post the stack trace you've got. If you don't then spend your effort on implementing AppDomain.UnhandledException. – Hans Passant Sep 24 '11 at 16:53

3 Answers3

6

My question is: Why didn't the exception get caught in the catch block above?

As David Stratton suggests, the system might have been out of disk space and not able to write to log file. There is also a chance that the process was terminated due to Corrupted State Exception that will not be delivered to your catch-all block in .NET 4. The exception that terminated process might have also been thrown from the thread that did not have catch-all.

Second, related question: Imagine if we use a third party library and we don't want any exception thrown.

I think that you will have to stop right there and rethink it. What you saying is that you are absolutely 100% sure that nothing ever can go wrong in the thirdparty library. There are certain exceptions (like OutOfMemoryException) that you should not be catching because your code simply does not know how to recover from them. The rule of thumb with exception handling is that you should only catch the exceptions that you fully understand and know how to recover from. Please take a look at this answer and the links in it.

What if the third party starts new thread and an exception is thrown there? Is there a way to handle this?

The best way to handle this is to rely on default CLR policy that will terminate your application. The only reasonable thing you can do is try to log it by subscribing to AppDomain.UnhandledException.

Community
  • 1
  • 1
Dmitry
  • 17,078
  • 2
  • 44
  • 70
  • first of all, thanks for your answer. very nice article about SEH. so if a corrupted state exception raised, will that be shown in call stack of crash dump? because i only saw the SqlException in crash dump. – ColdEar Sep 24 '11 at 17:16
  • also, none of the logging methods i used would log to that SQL server. – ColdEar Sep 24 '11 at 17:24
0

If you use Code contracts runtime checking I advice you to check compiled version of your DLL. Read this for details Why .net exception is not caught?

Community
  • 1
  • 1
Alexander Bartosh
  • 8,287
  • 1
  • 21
  • 22
0

Is it possible that there is another try/catch block inside that InsertSearch method, which has conditional throw statement.

The implementer of the 'DBManager' class, chose not to throw in case there is not enough space to write on the disk. Just a thought.

Hps
  • 1,177
  • 8
  • 9