views:

133

answers:

6

First, I'm sorry for what must be a duplicate post. I cannot seem to narrow my search down enough on SO and google to find what I'm looking for.

I'm currently working in a shop where they like their exceptions to bubble up. When the compiled app goes to test, it's a big pain trying to get the details of the exception (message and stack trace). Windows shows that familiar box that lacks any details what-so-ever.

After rescently spending close to an hour finding out that the test box has the wrong version of crystal reports, I added this simple code everone is probably familiar with.

    static void Main(string[] arg)
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run( ... );
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.ToString());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).ToString());
    }

This gets the job done, but I'm not allowed to check it in. Is there any way in the app.config or via registry setting to get the CLR to show or log exception details for a compiled .net app?

Thanks in advance for your help.

A: 

I am using WPF so here is where all the unhandled exceptions bubble out, it might be useful for your needs:

Private Sub Application_DispatcherUnhandledException(ByVal sender As Object, ByVal e As System.Windows.Threading.DispatcherUnhandledExceptionEventArgs) Handles Me.DispatcherUnhandledException
    'TODO: Log error'

    Dim sb As New System.Text.StringBuilder(e.Exception.Message & vbCrLf)

    Dim ex = e.Exception.InnerException
    While ex IsNot Nothing
        sb.AppendLine("______________ inner exception: ______________")
        sb.AppendLine(ex.Message)
        sb.AppendLine(vbCrLf)
        ex = ex.InnerException
    End While

    If MessageBox.Show(sb.ToString, "Exception caught", MessageBoxButton.OKCancel) = MessageBoxResult.Cancel Then Stop
    e.Handled = True
End Sub

Accept my apology I didn't have time to rewrite it, I just copied my original code, I am sure it's still helpful tho.

Thanks

Shimmy
+1  A: 

just use log4net if you want to configure your log output.

serhio
A: 

Shimmy's solution is handy if you know how to code in VB.NET.

You can then go recursively into ex.InnerException.InnerException....and so on...to construct a complete message

(1) if ex.Message is not null or Empty, show it.

(2) if ex.InnerException is not null show ex.InnerException.Message.

JMSA
A: 

You have the option of wrapping the debugging handling code in conditional compilation symbols. This would allow you to provide the verbose logging you wanted for testing purposes, but that would not be available to end-users in the release builds of the application.

Gareth Saul
A: 

Looks like you're missing the top-level try-catch in your Main() method. See one of my answers for an example.

And I wouldn't use a MessageBox, but one single static method that logs the problem in the way you want/need, then shows a generic "Unexpected fatal error occured. [Bla bla bla]" message and kills the running process on Ok.

peSHIr
A: 

Can you use the Enterprise Library? There are Exception Handling and Logging blocks which might be useful to you. You can configure the Exception Handling block to notify and rethrow the original exception and log the details with the Logging Block. It can be a bit of a steep hill to climb, to get to grips with it, but I think it'll be worth it in the end.

serialhobbyist