June 22, 2004
I just posted a new article on Code Project, User Friendly Exception Handling. This is a set of classes that deal with unhandled and handled exceptions through a consistent UI, as presented in Alan Cooper's great book About Face: The Essentials of User Interface Design.
Anyway, at the time of the unhandled exception, here's what you get for free:
- Display an automatic, Cooper-Approved(tm) exception interface
- Capture a screenshot of the user's desktop
- Build a string containing comprehensive diagnostic information
- Notify the developers via SMTP e-mail, and attach the screenshot
- Write an event to the event log
- Write a plain-text exception log in the application folder
I have used the hell out of this code and it works like gangbusters. There's nothing like an extremely tight loop between developers and exceptions to facilitate quick, responsive fixes to broken code. And since we have it set up to email every team member for every Unhandled Exception-- it's a therapeutic form of punishment, too!
Also, if anyone is interested in those animated GIF screenshots-- I had been looking for a simple tool to do this for literally years-- it's the archaic 1997 version of GifgIfgiF. Extremely old-school, but it still works great and generates very tiny, ultra-compatible animated Gifs. Of course you'll want to turn off all the crazy XP theming and revert to 256-color friendly Win2k style forms before you generate these kinds of Gif animations, too.
Download the VS.NET 2003 solution
Posted by Jeff Atwood
Have you looked into making your code a provider to the Exception Management Application Block. This would be really useful.
That's great-- I'm glad you found it useful. Keep me updated on your progress!
Oi: I have found your exception manager block very useful. I am using it to track and fix exceptions in a distributed .net application.
I am also using the enterprise patterns library, and have been considering adding your exception handling extension to it with the next revision (coming next month likely - October) to it.
The other thing I would like to do with it (if thats ok) is change it slightly so it sends an XML encoded attachement containing the exception details. I want to then have a receiver services (already mostly built) that takes the XML from the email, and inserts it into a database so that I can do more detailed classification/analysis of bugs with it....
I have one futher evil plan ;-) for it, that I won't go into detail about just yet as I am not sure if it will work or not yet, but would be very very cool....
It has been a lifesaver: I am in a situation where there is a custom developed legacy application whos datastructure and user interface is very.. well leaves something to be desired.
I have built a replacement for part of its front end using a .net c# winforms app. I have had some very difficult challenges to overcome in terms of twisting the legacy datastructure into something that can be used in a more modern object oriented approach, and something that the users can work with from a UI perspective that doesn't waste so much of their time and hair....(from pulling it out in sheer frustration)...
Fortunately, using the design pattern approach, and in particular Martin Fowlers domain design pattern (to seperate the mapping of the cludgy datastructure to my domain layer) I have been largely successful in getting it all working.
However, I ran into some really nasty issues on both the database side and the UI side.
The end platforms I am distributing the app to are highly varied, both in terms of OS (win 98-XP) and connectivity, and some users were experiencing exceptions that I could not reproduce on my machine.
I needed a way of getting all the execption details sent to me: using your handler I was able to pin down the source of the exceptions.
Turns out one was the dreaded winforms SEHException relating to the visual styles bug (mostly seemed to hit windows 2000 machines that did not have all the service packs in place).
Another was related to the speed/memory of the host machine triggered by auto-displaying a third party component combo box with a large number of items in it, which is why I couldn't reproduce it on my machine.
The last major issue was the fact that the legacy application database is not using proper primary keys and identity constraints - the developer is using a maxID+1 approach. That one is a bit of a long story...
The other bugs I fixed very quickly once I knew what they were, and the last one - well, I was able to use the exception information to show the legacy developer that in fact the problem was due to flaws in the database desgin, and not my application....
Sorry for the long message: at any rate -
I will add the XML attachment thing first to your library, since that will be easier to do than build up the handler for the enterprise library.
Your handling approach is so good, I think it will a very worthwhile addition to the enterprise library, which I am also finding very useful (the new version is very good, and has some key timesaving features). I will likely have to wait to tackle that excercise though, simply due to time constraints. (new baby on the scene in addition to the new job)
I am working in c#, so I am not as familiar with the VB side, but I think I can get it working. Your code is very well structured, so that makes it pretty easy to understand.
I will send you the code as soon as I get it working... I will also post up the email receiver processing component and exception manager database structure, once I get it cleaned up enough for public consumption.
The receiver I am hoping to setup as a service that simply listens for email coming in on a specified address (I have it working as a winforms app, but have some multithreading issues to solve yet: still struggling with threading :-).
When an email comes in, the subject will tell the receiver service factory what handler to generate. The factory will create a handler that has all the details for extracting the contents of the attachment, and routing the information into the relevant database. I am already using it for handling scada data information - so I just need to write a handler for the exception XML, and add it to my factory.
Course you could use Biztalk for that bit, but we are running tight budgets for software so I can't get the justification for bringing in another expensive server product. If I can get it cleaned up enough, I'll just throw it up on the web, and hopefully other people can benefit from a simple email attachment to database processor.
It uses the CSphere email component to do the mail handling. Csphere is open source as well - these tools have saved me a lot of time, so I am keen to contribute back, which is why I plan to release the code to the community.
The final peice of the puzzle that I mentioned is geared towards automating the tracing down of information regarding potential causes of exceptions....I have found that the exception messages are useful, but not the end of the story, and that I spend a great deal of time looking up what paths an exception might stem from.
I have what I think (hopefully) is a good idea for that...
I am very impressed with your "User-Friendly Exception Handling" class. Do you have any instructions for using this code with vb.net 2005?
Under vb.net 2003, I used "Public Sub Main" to start the error handler.
Under vb.net 2005, I am no longer using "Public Sub Main". A form by the name of mdiMain is set as the startup form and "Enable Application Framework" is checked.
How should the code be implemented using the Application Framework?
I am very impressed with the level of thought and completeness of your exception handler!!!
under vb.net 2005, I have successfully used the code blocks with some modifications.
First, you will need to change the settings in the app.config file to match the new My namespace of vb.net 2005.
Second, the best place to add the handler is in the MyApplication_Startup routine of the MyApplication class.
There were a few other changes that I had to make, but they were not that difficult.
I'm sure that Jeff will eventually have time to make the modifications to the code block.
Please can anyone tell me how i can use it in CS 2005 C# windows application
Same question as Aman, I'd really like to use it in 2005 (C#/VB).
It seems a beautiful tool, but I can't make it work correctly.
Currently, it's nearly working in ms C#2005 application outside of the ide) : I get the screenshot, I get the file, no email or system log (maybe my mystake), but above all, I'm getting eventually a really unhandled "System.MissingFieldException" ...
(and no nice dialog, of course :) )
Looks like a great component. I'd love to use this in VS2K5!
I successfully used the following thing - a href="http://msdn2.microsoft.com/en-us/library/aa480461.aspx"http://msdn2.microsoft.com/en-us/library/aa480461.aspx/a in one of my projects, but I have almost the same problem with my client application which works with my web service. All exceptions from web service are wrapped to SoapException and I can`t find any good solutions for this case.
Aren't there any privacy concerns with e-mailing a screen dump of the users desktop without their consent?
I appreciate that if it's in a company environment then the company has a right (sort of) to see what they are doing but with a home user you might get private e-mails, pictures, who knows what coming along as well as your details of the bug!
Very well written piece of code with all the details I've ever wanted. Started chasing my tail though when I saw the comment "generic exception handler; the various specific handlers all call into this sub", but didn't find that to be true. Also the comment "don't send ANOTHER email if we are already doing so!" indicates you expect to go through ExceptionToUI after you've e-mailed during a handled exception, but your sample apps go straight to ShowDialog, bypassing all of that. This causes other trouble, like KillAppOnException didn't work for handled exceptions and setting SendMail to false didn't apply to handled exceptions either.
I'm looking at rearranging it so my Catch block would call GenericHandler, it would have the overloads, similar to ShowDialog and eliminate the ShowDialog overloads. The two exception event handlers would do a little something then call GenericHandler. After that, everyone is the same.
If I'm missing something, or otherwise off-base, please stop me.