Implementing an exception handling policy

Joined
Oct 15, 2007
Messages
3
Programming Experience
5-10
Hello,

I have a fairly large console application that is setup the following way:

Console Project: Executes Business code to process.
Business Logic Layer Project: Contains all business rules to process
Business Entities Layer Project: Contains all data objects i.e.(DataSets)
Data Access Layer Project: Contains Data access ADO helpers.

Anyway this applications main function is to accept parameters and process the creation of files that are generated from the data base as well as process incoming files and upload them to the database.

I am trying to implement exception handling policies into my application but since there is really no exceptions i can plan for and catch and recover from i am trying to log all exceptions at an application level.


VB.NET:
Module PopsIFConsole

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Sub Main()
        AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

        Dim customerBC As New ARCustomerBC()
        customerBC.WriteCustomerFile()

        Dim accountsPayableBC As New AccountsPayableBC()
        accountsPayableBC.WriteAccountsPayableFiles()

        Dim openObligations As New AROpenObligationsBC()
        openObligations.ProcessOpenObligations()

        Dim newObligations As New ARNewObligationsBC()
        newObligations.WriteNewObligationsFile()

        Dim omsFileInterface As OMSFileInterface = New OMSFileInterface()
        omsFileInterface.CreateOMSMasterFile("LFR")
        omsFileInterface.CreateOMSMasterFile("BWK")

        System.Console.WriteLine("Done")
        System.Console.Read()
    End Sub

    Private Sub HandleException(ByVal ex As Exception, ByVal policy As String)
        Dim rethrow As Boolean = False

        Try
            rethrow = ExceptionPolicy.HandleException(ex, policy)
        Catch innerEx As Exception
            Dim errorMsg As String
            errorMsg = String.Format("An unexpected exception occured " & _
                "while calling HandleException with policy '{0}.{1}{2}'", _
                policy, Environment.NewLine, innerEx.ToString())

            System.Console.WriteLine(errorMsg, "Application Error")

            Throw ex
        End Try

        If (rethrow) Then
            ' WARNING: This will truncate the stack of the exception
            Throw ex
        Else
            System.Console.WriteLine("An unhandled exception occurred " & _
                "and has been logged. Please contact support.")
        End If
    End Sub

    Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
        If TypeOf e.ExceptionObject Is System.Exception Then
            HandleException(CType(e.ExceptionObject, System.Exception), "Global Policy")
        End If

        If Not e.IsTerminating Then
            ' Exception occurred in a thread pool or finalizer thread
            ' Debugger launches only explicitly
        Else
            ' Exception occurred in managed thread
            ' Debugger will also launch when not launched explicitly
        End If


        ' This is a final release; 
        ' logging is done to Syslog and over the Web if possible
        ' Debugger is mostly not available
        If Not e.IsTerminating Then
            ' Exception occurred in a thread pool or finalizer thread
            ' Application keeps open
        Else
            ' Exception occurred in managed thread
            ' Application is closing, so you should log now
        End If
    End Sub
End Module

The problem with this code is that the actual exception appears to be swallowed by the CLR and does not get logged properly in the application event log. Instead of the actual inner exception being logged a CLR exception is logged and the app thread is terminated and the application is thrown into debug mode from the CLR. What I need to happen is the application log the inner exception and the application exit gracefully.

I have done this type of policy handling and logging in windows forms and ASP.NET but I am not familiar with how to handle this in a console application. I know there is some known issues with how the CLR terminates console application main threads when an exception occurs but have been unable to find any method that satisfies my desired result.

If anyone has anything that can help with this it would be greatly appreciated.
 
Last edited by a moderator:
Just a follow up

Saw several views concerning my post but no responses at this time.

The main reason this is important for me to figure out is because if I don't log exceptions at an app or appdomain level I will have to go back thru all of my business code and wrap everything with try/catch blocks and rethrow all exceptions to my exception handling policy.

This will not only be a pain to implement as well as redundant but will cause considerable overhead for the runtime of my application.

Hope that someone has run into this situation.

Again Thanks,

Todd
 
Issue Resolved

I found out what my issue was.

Unhandled exceptions that occur in threads other than the
application's main thread are swallowed by the CLR. This includes
manual threads, thread pool threads, and the CLR's finalizer thread. If
your application is a console application, the CLR outputs exception
text to the console (though your application keeps running). If your
application is not a console application, there is no outward
indication when an exception occurs and your application keeps running.

So therefore when my exception was bubbled up to the Main method in the call stack it caused the exception to be printed out to the console but instead threw a CLR exception that was actually logged.

By creating a new class that actually processed the code that could throw an exception in my main it caused the exception to be bubbled up to that class and that class could implement the policy handler and log the exception then the CLR exception was thrown.

AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException

Dim someCode As New ClassA()
someCode.DoWork()

Keep in mind that I did not need to wrap the code in ClassA in a try catch.

The only other event needed in the main console class is this:

Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
If TypeOf e.ExceptionObject Is System.Exception Then
HandleException(CType(e.ExceptionObject, System.Exception), "Global Policy")
End If

Environment.Exit(0)
End Sub

With this in place now all unhandled exceptions are bubbled up to the call stack and logged.

http://msdn.microsoft.com/msdnmag/issues/04/06/NET/
Edit/Delete Message
 
Back
Top