Blogger :
Sam Gentile
All posts :
All posts by Sam Gentile
Category :
WSCF/WCF
Blogged date : 2006 Aug 05
In the last post, I talked about how we had reached Iteration 33 and gone to CTP with a large International bank. I alluded to some problems. Of course, one of the CTP's main purposes was to find problems and learn from them. We ended up having a variety of problems. There were initial problems in the Click-Once deployment. We built a WIX MSI (great work done by mostly Aaron & Brad) that installs our database scripts, sets up our config files, installs our WCF Services and sets up the service for the Click-Once Deployment of our client. This is installed server-side. The Click-Once deployment failed, and our excellent person on the scene went to an xcopy deployment, and as you will see later, that caused some funky issues, although far from being the only and main cause. (Note: I have just split the post into two and the next part will talk about our solutions with the Service Factory, Exception Management and Logging Blocks).
The gist of it is that our client never came up (-. Trying to find out why proved to be a two-day somewhat intense struggle for Steve and I who were the main leads dealing with our man in Paris. The first major realization is that all of us on the whole team had done a real crappy job dealing with Indigo Service exceptions not catching the variety of exceptions that could come up including the service not being there. We did have a Global Exception Handler and had a custom dialog with the nice error message. While realizing our shortfalls, the immediate mystery was why the Global Exception Handler did not catch and show these particular exceptions. Left to their own devices, these exceptions would bubble up and evetually show themselves as CAB exceptions. Our global handler handled the Application.ThreadException. What we forgot was to handle the AppDomain.UnhandledException event. It would be something like this:
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
So, Steve and I starting doing what any good Developer would do in trying to narrow down the problem and rule things out. The big mistake is that we as a team had failed to Instrument the app with logging (we had a brief flirtation with log4net) and Steve and I had to narrow down by exclusion. The first obvious place was checking if the AzMan roles were prohibiting the client from coming up. When the Role was switched to the moral equivalent of "Read Only", the client properly displayed the "You are not authorized for this role" message. So it was authenticating, getting to our service and getting the role from the principal out of AzMan.
Steve and I then begun to create custom clients with poorman's logging. We did find Services that had failed and the exceptions were uncaught but there was still a main reason why the client was not coming up at all. We then commented out one of the CAB modules from the ProfileCatalog.xml file that CAB loads and lo and behold, it came up (somewhat)! We then switched to why that particular CAB module was not loading. We created some custom CAB logging, and long story short, it turned out to be that in failed Click-Once (remember that?) and the resulting XCopy deployment, the Report Control that we are using in the client was not there and stopping the entire CAB module from loading!
This is going too long, so I am going to split into another post on actually using the Service Factory, Exception Management and Logging Blocks. Also, I ponder whether Agile or Extreme Programing development and "Continous Architecture" and relentless continous delivery of business value functionality every single week ever really allows time to build adequate framework level stuff like this (logging, etc).