In the last release of our LOB application we added a feature whereby unhandled exceptions are now emailed (along with a stack trace) back to us. We found there are a few small, stupid errors that got past our processes (not surprising really as we seem to have an infinite number of boundary cases) and a relentless list of issues from a third party Gantt control (GDI+ errors and out of memory errors).

It turns out that our users we not telling about these bugs and just living with them! Even more surprising is that they seem to be full of praise for this software; what must the standards of other packages be like?

At least we can address them now, thanks to the influx of emails.

So that's my tip -- automatic error reporting back to base because users don't seem to want to report bugs.

not a tip, just that what you said is true, I have several apps that are part of a system and we know that users will just keep using the app and may never tell us about a problem in some cases. we have also went more and more to gathering logs and finding things from them not form users telling us about issues.

I've used automatic error reporting in a few projects, including ye olde C9 International Avatar Creator (now there's a blast from the past). What I learned from that is that just the output from ToString (or even the result of serializing the entire exception object) are often not enough to track down a repro case, especially if you have no way to contact the people who sent the report.

We not only make the application email us the error we also record it in a database so we can analyse and target the frequent errors for earlier remediation.

Our next error related thing is to make the error reporting module check for a friendly error message translation by looking for the signature of the error in a translation table. That way if any technical error messages are annoying the user we can quickly but a translation into the data without having to recompile and deploy a new version of the application.

I've used automatic error reporting in a few projects, including ye olde C9 International Avatar Creator (now there's a blast from the past). What I learned from that is that just the output from ToString (or even the result of serializing the entire exception object) are often not enough to track down a repro case, especially if you have no way to contact the people who sent the report.

yeah you have where and when but not "How" ... method parameters can help, but sometimes you need more and sometimes you need to talk to the user, I know...

Always make sure where possible that when your source is pulled from the source server onto a new machine, that it will compile i.e ensure any dependencies are placed into a third party folder, especially NuGet fetched .dll's

Always make sure where possible that when your source is pulled from the source server onto a new machine, that it will compile i.e ensure any dependencies are placed into a third party folder, especially NuGet fetched .dll's

++

Having a build server which automatically cleans and refreshes the entire source code across the company every night, checks that it builds and then runs unit tests, and emailing the person responsible for every failed unit test and every failed compile makes a huge amount of difference to the productivity of the company as a whole.

Also, having a tool that will tell you what percentage of your codebase is covered by your unit tests is a good way of helping developers write good unit tests

@blowdart: In fact, I'm hesitant to let management see any kind of code metric. Depending on your management you can end up with them liking to see a certain number of lines per day or some such nonsense. We try to boil our work items down into agile/kanban points to provide an abstract metric that still gives an accurate sense of progress.

Not everybody can do agile, but the point system can help to weight certain work items as being more complex/time consuming so you don't get dinged for taking a whole day on a single work item whereas somebody else may do more.

We serialize the exception save it in a database and send emails to the developers, but as Sven said sometimes that is not enough, is there a way to capture the Locals and saves those too? Otherwise we end up on the test server trying to repro the bub.

We serialize the exception save it in a database and send emails to the developers, but as Sven said sometimes that is not enough, is there a way to capture the Locals and saves those too? Otherwise we end up on the test server trying to repro the bub.

As far as I can tell, there's no easy way to capture all the locals. You either end up adding a lot of plumbing to every method, or you have to do a Dr. Watson style memory dump and try to debug that. If anyone knows a better way, I'd like to know it too.

@Sven Groot: Redgate has their SmartAssembly product. I know some people who use it, and say it works pretty well. The advantage of a product like this is that it injects the functionality into the compiled assembly, so you don't have to write a bunch of plumbing code.

As another general tip, remember that errors can generally be divided into three categories:

Errors that you can handle silently without any user interaction

Stuff that requires you to tell the user "Oops, something happened, try again/close the application and try again"

Finally, errors that cause the application to completely stop

Theoretically you can recover from a lot and continue, but as you find places where errors could occur, you need to make the decision about what can be handled with each level of severity. For example, you don't want to try and silently continue if there is the risk of data loss. Certain commits might be ok to throw a warning about, and others might need to you to allow or cause a full crash in order to prevent damage or to let the user know that something is really wrong and they shouldn't waste their frustration on trying it over and over.

Corollary: try { } catch ( Exception ex ) { /* no rethrow */ } anywhere other than at the root of a thread or the program doing anything other than logging the exception and exiting might sound like you're being kind to your customers, but in reality you're just being unkind to your developers

That construct can allow you to continue over an exception that you shouldn't be continuing from, and will end up having corrupted a whole load of internal state making your life waaay harder when you come to debug.

Design your APIs so that you know what exceptions they might spit out, and capture only the ones you know you can continue from!