Mohsen
Mohsen

Reputation: 1118

Catch All Unhandled Exceptions

I'm going to catch all unhandled exceptions in my Winforms app. Here is the shortened code:

[STAThread]
static void Main()
{
    if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe"))
    {
        Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod);
    }

    Application.Run(new frmLogin());
}

private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
    Exception ex = t.Exception;
    StackTrace trace = new StackTrace(ex, true);

    var db = new MyDataContext();

    Error error = new Error();
    error.FormName = trace.GetFrame(0).GetMethod().ReflectedType.FullName;
    error.LineNumber = trace.GetFrame(0).GetFileLineNumber();
    error.ColumnNumber = trace.GetFrame(0).GetFileColumnNumber();
    error.Message = ex.Message;

    db.Errors.InsertOnSubmit(error);
    db.SubmitChanges();

    if (new frmError(ex).ShowDialog() != DialogResult.Yes)
        System.Diagnostics.Process.GetCurrentProcess().Kill();
}

The issue is that sometimes FormName, LineNumber and ColumnNumber are not correctly returned. Here is the result that I sometimes get:

  --FormName--          --Line/Column--    --Message--
System.Linq.Enumerable       0  0   Sequence contains no matching element
System.RuntimeMethodHandle   0  0   Exception has been thrown by the target of an invocation.
System.Number                0  0   Input string was not in a correct format.
System.Number                0  0   Input string was not in a correct format.
System.ThrowHelper           0  0   Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

As you can see, LineNumbers and ColumnNumbers are 0. FormName is System.Linq.Enumerable ...

How can I solve the problem?

Upvotes: 0

Views: 621

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70701

How can I solve the problem?

When no .pdb is present for a given module, the stack trace information will necessarily not be able to include file names, line, or column numbers.

To get them, you need to make sure you have the .NET .pdb available and loaded. There are a number of resources available which describe how to do this. See Cannot step into .NET framework source code, for example, or Advanced .NET Debugging - PDBs and Symbol Stores. You can use your favorite web search engine to find additional resources.

I'll note also that you are describing the type name as the "FormName", which is incorrect. It's only the form name when the exception was in fact thrown by your form. Unhandled exceptions are always bugs, and as such are very often thrown by framework or other library code, and the types won't be forms.

I will also mention that catching all exceptions is useful only for diagnosing bugs. This should not be used as an attempt to improve general reliability of a program (except to the extent that better diagnosis can allow you to fix bugs). When an unhandled exception occurs, you should log it and then kill the process. Allowing a process to continue executing after an unhandled exception occurs is dangerous for your data, and can lead to complacency with respect to bug-fixing.

Upvotes: 1

Related Questions