Print Page | Close Window

Exception eaten in Windows service?

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce Classic
Forum Discription: For .NET 2.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=4459
Printed Date: 04-May-2024 at 3:48pm


Topic: Exception eaten in Windows service?
Posted By: stevenr
Subject: Exception eaten in Windows service?
Date Posted: 04-Oct-2013 at 5:43am
The system I'm working on consists of a client application where users can submit requests for work in a database table, and a Windows service that polls this table every x seconds. If there is work to be done, the service calls into a module that processes the request. If there is no work to be done, the service goes back to sleep and checks again in x seconds. This is all set up and has been working for almost a year now. The problem is that recently, there were cases being reported of requests for work that were submitted, but never processed. Upon further investigation, I learned that the service had run into an unhandled exception but that exception was never caught and logged. Here's the main part of the service:

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
    try
    {    
        // Check if there is work to be done
        if (there is work to be done)
        {
            this.timer.Stop();
            // Call the module that does the actual work
            MyWorkerModule.DoWork();
        }
    }
    catch (SystemException ex)
    {
        // Log the exception
    }
    finally
    {
       if (!this.timer.Enabled)
       {
           this.timer.Start();
       }
    }
}

The service also handles the AppDomain.CurrentDomain.UnhandledException event where it logs any exceptions.

My first approach was to find out if there was anything wrong with the implementation of the service itself. I have a command-line executable that I use for actual debugging that follows the exact same code path as the service and the executable does catch the exception. Here's the full stack trace that the executable caught:

IdeaBlade.Persistence.PersistenceServerException: The conversion of a datetime data type to a smalldatetime data type resulted in an out-of-range value.
The conversion of a datetime data type to a smalldatetime data type resulted in an out-of-range value. ---> System.Data.SqlClient.SqlException: The conversion of a datetime data type to a smalldatetime data type resulted in an out-of-range value.
The conversion of a datetime data type to a smalldatetime data type resulted in an out-of-range value.
   at IdeaBlade.Persistence.RemotingPersistenceServerProxy.CheckConnection(Exception pException)
   at IdeaBlade.Persistence.PersistenceServerProxy.Fetch(SessionBundle pBundle, IEntityQuery pQuery)
   at IdeaBlade.Persistence.PersistenceManager.XFetchDataSet(IEntityQuery pEntityQuery)
   --- End of inner exception stack trace ---
   at IdeaBlade.Persistence.PersistenceManager.HandlePersistenceServerException(Exception pException, Boolean pTryToHandle, PersistenceOperation pOperation)
   at IdeaBlade.Persistence.PersistenceManager.XFetchDataSet(IEntityQuery pEntityQuery)
   at IdeaBlade.Persistence.PersistenceManager.XFetch(IEntityFinder pEntityFinder, WorkState pWorkState)
   at IdeaBlade.Persistence.PersistenceManager.XFetch(IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy, WorkState pWorkState)
   at IdeaBlade.Persistence.PersistenceManager.XGetEntities(IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy, WorkState pWorkState)
   at IdeaBlade.Persistence.PersistenceManager.GetEntity(IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy)
   at IdeaBlade.Persistence.PersistenceManager.GetEntity[T](IEntityQuery pEntityQuery, QueryStrategy pQueryStrategy)


I even tried catching and logging unhandled exceptions in the worker module itself:

public class MyWorkerModule
{
    public void DoWork()
    {
        try
        {
            // Actual work done here.
        }
        catch (SystemException e)
        {
           // Log the exception
        }
    }
}

But whatever I do, the service just won't catch and log the exception. I posted this question on MSDN and the response I got was that the way this service is implemented, it should be able to catch exceptions. After exhausting every avenue, I have come to believe that somehow IdeaBlade eats the exception somewhere along the way, *only* when executing from within the context of a service (remember, a command-line executable following the exact same code path does catch the exception). I'm not concerned about recovering from the exception; my goal here is to know that an exception occurred because a request can consist of thousands of records to be processed and it would be very helpful to know exactly where a problem occurs.
So my question is: is there a particular setting that I need to configure to allow the exception to reach the catch block? The service runs on .Net 3.5 on Windows Server 2008.



Replies:
Posted By: kimj
Date Posted: 04-Oct-2013 at 10:02am

DevForce does not eat the exception, and does not know that it's running within the context of a Windows Service.

Your DoWork method is running on a background thread, and I have read that exceptions on a background thread may not always be handled by an AppDomain.CurrentDomain.UnhandledException handler.  It's odd, though, that your try/catch handler isn't catching the exception, although you could try catching "Exception" and not "SystemException", since the exception thrown by DevForce will likely be a PersistenceServerException, which doesn't inherit from SystemException.
 
Another thing to try is to add a handler for PM.PersistenceServerError.   


Posted By: stevenr
Date Posted: 04-Oct-2013 at 11:30am
Yep, that was it. If I try catching "Exception", it is logged.



Print Page | Close Window