[C#] Catching exceptions in Main()

Soldato
Joined
12 Apr 2004
Posts
11,788
Location
Somewhere
As title... I've encased the contents of the Main() method (as the entry point for a Windows form) in Program.cs in a try {} catch {} block. This all works fine in debugging mode, but as soon as I compile, run and get an exception for whatever reason, I get the normal error message telling me there's been an error. Why is it not catching the exception? :confused:
 
because it will only break to the compiler when in debug mode. I assume your running it in release mode or running the .exe directly?

You should use the microsoft exception management block and then just write any exceptions out to the app log
 
But surely if he is catching the exception and trying to handle it in the catch block it should be caught anyway (I've not really used exceptions in C#, but I would expect this to happen).

Code example? Maybe its throwing an exception which your not catching?
 
Yep, it should be caught regardless of whether you're running Debug or Release. Perhaps there's something in the top-level catch {} block that's throwing another exception back up to the runtime.

Do you have a code snippet you could post?

cheers
v.f.
 
Well, here's my Main() method code:

Code:
        [STAThread]
        private static void Main(string[] args)
        {
            try
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new formMultiBackup(args));
            }
            catch (Exception exception)
            {
                // Exception caught - not much we can do about
                // it at this stage, but we can log it at least

                // Inform user
                string title = "Error";
                string message = exception.Message;
                MessageBoxButtons buttons = MessageBoxButtons.OK;
                MessageBoxIcon icon = MessageBoxIcon.Error;
                MessageBox.Show(message, title, buttons, icon);

                // Log error
                LogError(exception);
            }
        }
and my exception is being thrown like this:
Code:
        private void buttonTest_Click(object sender, EventArgs e)
        {
                throw new Exception("This is a test exception.");
        }
When I click this button, I get exactly the same message on the window that pops up when there's an unhandled exception, so either it's not being caught, or it's getting rethrown for some reason :confused:

Cheers.
 
Last edited:
What type of exception are you throwing? What happens if you just put
throw new Exception("test"); inside the try block and get rid of everything else?
 
That's weird... I just tried what you said and it worked fine, even after being compiled... It even works fine when I stick it in the formMultiBackup constructor. However, it doesn't work when I put it in the button click event handler :confused:
 
Aha. Presumably the button click event is handled by a seperate thread, so it won't be caught by the main method? I'm not sure exactly what the semantics are here, but I'm guessing:
- Events are handled by a seperate / new thread.
- If you start a thread then throw an exception from inside it you can't catch the exception from where you started the thread (ie: the main method).
 
Hmm, I've just tested that with a couple of assertions, and the thread that handles the event has the same ID as the thread that starts the form object. Also, the debugger seems fine with an exception being thrown from the event handler.
 
The debugger will obviously catch an exception thrown during anything, but does control actually go into the catch block? I'm guessing not, since it should do exactly the same thing in both cases.
 
Yup. I've put an assertion in the catch block, and that's getting fired when the exception occurs during debugging.

I tried it again when it's compiled (using another exception in the catch block this time, rather than an assertion) and control does not appear to be entering the catch block.
 
Lagz was on the right track when he said it was something to do with threading. It looks like the click event is triggered by a different thread (the message loop may be running on an implicit worker thread).

The strange thing is that your original code worked in both Debug and Release mode when executed within the debugger, but both triggered unhandled exceptions when executed outside of the debugger context (i.e. there was no difference in behaviour between Debug and Release).

It looks like you need to add a handler for the ThreadException event on the Application object. This should allow you to handle exceptions thrown from any thread in one place.

Code:
Application.ThreadException += new ThreadExceptionEventHandler(Handler);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Hope this helps.

cheers
v.f.
 
Thanks, this almost works :p

When an exception is thrown at some point during the program's execution, the event handler I added in Program.cs catches the event, does its stuff and the program continues, but when I try this in Debug mode (not Release mode), I get an "Exception was unhandled by user code" message come up...
 
Looks like this is a known "feature" in Visual Studio 2005. Go to Tools -> Options -> Debugging -> General and turn off "Enable Just My Code (Managed Only)" and normal service shold be resumed ;)

cheers
v.f.
 
Back
Top Bottom