I'm wondering why I don't get an error on this Windows Form C#

On this form, if I get an error in the catch block, I would expect an "unhandled exception" issue.  This is important because it's being run from Task Scheduler and we're not being notfied of the failure.  Because of the finally block the program exits gracefully.  Without the finally block the program just hangs.  Why am I not getting the unhandled exception?

    public partial class frmRunProcesses : Form
    {
        private string _DefectPath = "";

        public frmRunProcesses()
        {
            InitializeComponent();
        }

        private void frmRunProcesses_Load(object sender, EventArgs e)
        {
            try
            {
             Note:  I added these throws in just to test error trapping
                throw new Exception("can't write");

                this.GetSettings();

                Processing p = new Processing(Application.StartupPath + @"\NPSEDIConfig.xml");


                if (!p.ProcessAll("scheduled"))
                {
                    throw new Exception("At frmRunProcesses_Load:\n\r\n\r" + p.ErrMess);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("can't write");
                if (this._DefectPath.Trim().Length != 0)
                {
                    this.WriteMessage('E', ex.Message, this._DefectPath);
                }
                else
                {
                    this.WriteMessage('E', ex.Message, Application.StartupPath + @"\");
                }
            }
            //finally
            //{
            //    Application.Exit();
            //}

        }

        private void GetSettings()
        {
            try
            {
                PkgSettings ps = new PkgSettings(Application.StartupPath + @"\Config.xml");
                if (ps.GetSettings() == 0)
                {
                    this._DefectPath = ps.DefectPath;
                }
                else
                {
                    throw new Exception("Cannot Get Settings:\n\r\n\r" + ps.ErrMessage);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("At GetSettings:\n\r\n\r" + ex.Message);
            }
        }

        private void WriteMessage(char mType, string Message, string wPath)
        {
            StreamWriter sw = new StreamWriter(wPath + "ScheduledRunErrLog.txt", true);
            sw.WriteLine(DateTime.Now.Year.ToString()
                + DateTime.Now.Month.ToString().PadLeft(2, '0') + " "
                + DateTime.Now.Day.ToString().PadLeft(2, '0') + " "
                + DateTime.Now.Hour.ToString().PadLeft(2, '0') + " "
                + DateTime.Now.Minute.ToString().PadLeft(2, '0') + " "
                + DateTime.Now.Second.ToString().PadLeft(2, '0') + "| "
                + mType.ToString() + ": " + Message);
            sw.Flush();
            sw.Close();
        }
    }
LVL 4
g_johnsonAsked:
Who is Participating?
 
it_saigeConnect With a Mentor DeveloperCommented:
Let me see if I can explain what is happening here.  In a standard Try...Catch block, you try to complete the task and catch any problems.  How you handle those problems is up to you (rethrow the exception, throw a new exception, write to a log file or [the oft dreaded] do nothing).  When you handle the problem with a new throw or rethrow, it is up to the calling method (in this case, since it is in the load event, the calling method is most likely main) to handle the exception since the exception is bubbled up to it.

Most of the time, Main does not have a Try...Catch block, so what you get presented with instead is:Capture.JPG
If this running as a scheduled task and the user is not logged in, then you do not get a  message box because the task scheduler is a service and does not interact with the desktop, so your application hangs because it is waiting for someone to make a choice ('Debug' or 'Close program' in this case).

Which is where  the events in the Program.cs would come into play.  They would catch the exceptions and log them.

When you add ...Finally to the Try...Catch equation, the finally always processes.  So your finally is basically telling the application to stop running, which closes the above mention window.

-saige-
0
 
SammyCommented:
Both exception and finally clause are reached
When you run this code you will get a message box with "Exception thrown Something went wrong!" then another messagebox with "Finally Reached"

            try
            {
                throw new Exception("Something went wrong!");

                DoStuff("Move");


            }
            
           
            catch (Exception ex)
            {

            MessageBox.Show(String.Format("Exception thrown {0}", ex.Message));
            }
          

            finally
            {
                MessageBox.Show("Finally Reached");
            }

Open in new window

0
 
g_johnsonAuthor Commented:
Sammy -- thanks.  That's is what's happening, of course.  But, when I have an exception in the Catch block, shouldn't I have a fatal error?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
it_saigeDeveloperCommented:
The only exception that is never captured by the running assembly is the StackOverflowException.  All other exceptions should be catchable (even though in certain situations; catching exceptions seems to be quirky; e.g. External component exceptions do not always get caught.)

The best way that I have found to combat this is to use the Application.ThreadException and AppDomain.CurrentDomain.UnhandledException events to try and capture any untrapped exceptions; e.g. -

Program.cs
using System;
using System.Windows.Forms;

namespace ExceptionExample
{
	static class Program
	{
		static Program()
		{
			Application.ThreadException += OnThreadException;
			AppDomain.CurrentDomain.UnhandledException += OnApplicationUnhandledException;
		}

		/// <summary>The main entry point for the application.</summary>
		[STAThread]
		static void Main()
		{
			new frmRunProcesses();
			return;
		}

		#region Event Handler Methods
		private static void OnThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
		{
			// Write your log message here.  You access the exception from the e Argument:
			// e.Exception
		}

		private static void OnApplicationUnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
			if (e.IsTerminating)
			{
				object o = e.ExceptionObject;
				// o in this case now represents an exception object, not that same as an exception class.
				// string.Format("{0}", o);
				// o.ToString();
			}
		}
		#endregion
	}
}

Open in new window


Ultimately, this raises the question.  Are you certain that you are excepting and how do you know this (I assume it's just because of the application hanging)?

-saige-
0
 
g_johnsonAuthor Commented:
it_saige -- That's a little over my head, unfortunately!  but, I'll try to answer your question.  As presented, when I hit the first Throw, it does indeed take me to the Catch.  Then, inside the Catch, I do another Throw.  That is unhandled and this is where I would expect the app to end ungracefully with a "exception not handled" error.  Instead, if the finally block is not active it just hangs.  If the finally block is active the program ends.

The only reason this matters is that we are having problems running it from Task Scheduler, and we would like to see Task Scheduler report the error.  Since the program ends "gracefully" (with the finally block in place), Task Scheduler just reports a normal end to the process.
0
 
g_johnsonAuthor Commented:
Perfect!  Thank you.  That's what I needed to understand.
0
All Courses

From novice to tech pro — start learning today.