What is the best way to collect crash data? - c#

So I am sold on the concept of attempting to collect data automatically from a program - i.e., popping up a dialog box that asks the user to send the report when something goes wrong.
I'm working in MS Visual Studio C#.
From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run? Like this:
try
{
Application.Run(new myMainForm());
}
catch (Exception ex)
{
//the code to build the report I want to send and to
//pop up the Problem Report form and ask the user to send
}
or does it make sense to put try/catch loops throughout pieces of the code to catch more specific exception types? (I'm thinking not because this is a new application, and putting in more specific exception catches means I have an idea of what's going to go wrong... I don't, which is why the above seems to make sense to me.)
-Adeena

I think you are right, you would not know what's going to go wrong, which is the point.
However, you might as well consider adding a handler to the ThreadException event instead.
The code above will work but there will be scenarios where multi threading might be an issue with such code, since not all code inside your windows forms program will be running in the main Application.Run loop thread.
Here's a sample code from the linked article:
[STAThread]
static void Main()
{
System.Windows.Forms.Application.ThreadException += new ThreadExceptionEventHandler(ReportError);
System.Windows.Forms.Application.Run(new MainForm());
}
private static void ReportError(object sender, ThreadExceptionEventArgs e)
{
using (ReportErrorDialog errorDlg = new ReportErrorDialog(e.Exception))
{
errorDlg.ShowDialog();
}
}
More documentation on MSDN.
On a minor point, using the ThreadException event also allow your main message loop to continue running in case the exception isn't fatal (i.e. fault-tolerance scenarios) whilst the try/catch approach may requires that you restart the main message loop which could cause side effects.

From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run?
Sure and always.
You should use Try/Catch-Blocks wherever you do something critical, that might raise an exception.
Therefore you can not really stick to a pattern for that, because you should now, when what exception will be raised. Otherwise these are unhandled exceptions, which let your program crash.
But there are many exceptions, that need not to stop the application entirely, exceptions, that just can be swallowed over, as they are expected and do not critically need the application to stop. Example for that are UnauthorizedAccessExceptions when moving or accessing data with your programm.
You should try to keep you Try/Catch-Blocks as small as needed, as well as to use not too much of them, because of performance.
Some out there use Try/Catch for steering the program's execution. That should entirely be avoided wherever possible, cause raising an Exception is performance killer number 1.

Wrapping a try catch around the whole application will mean the application will exit upon error.
While using a try and catch around each method is hard to maintain.
Best practice is to use specific try catches around units of code that will throw specific exception types such as FormatException and leave the general exception handling to the application level event handlers.
try
{
//Code that could error here
}
catch (FormatException ex)
{
//Code to tell user of their error
//all other errors will be handled
//by the global error handler
}
Experience will tell you the type of things that could go wrong. Over time you will notice your app often throwing say IO exceptions around file access so you may then later catch these and give the user more information.
The global handlers for errors will catch everything else. You use these by hooking up event handlers to the two events System.Windows.Forms.Application.ThreadException (see MSDN) and AppDomain.UnhandledException (see MSDN)
Be aware that Out of Memory exceptions and StackOverflowException may not be caught by any error catching.

If you do want to automatically get stack traces, Microsoft do allow you to submit them via the Error Reporting Services. All you need to do is sign up for a Digital Certificate from VeriSign and register it (for free) with Microsoft.
Microsoft then gives you a login for you to download the mini-dumps from a website, which are submitted when a user clicks "Send Error Report".
Although people can hit "Don't Send", at least it is a Microsoft dialog box and possibly not one that you have to code yourself. It would be running 24/7, you wouldn't have to worry about uptime of your web server AND you can submit workaround details for users AND you can deliver updates via Windows Update.
Information about this service is located in this "Windows Error Reporting: Getting Started" article.

The best approach is to sing up for
AppDomain.UnhandledException and Application.ThreadException In your application's main function. This will allow you to record any unhandled exceptions in your application. Wraping run in a try catch block does not catch every thing.

if you just want to capture crashes, then ignore all errors and let DrWatson generate a minidump for you. Then you can look at that ina debugger (windbg is preferred for minidumps) and it'll show you the line your code went wrong on, and also all the parameters, stack trace, and registers. You can set Drwatson to generate a full dump where you'll get an entire memory core dump to investigate.
I wouldn't recommend putting a try/catch around the entire app unless you want your app to never "crash" in front of the user - it'll always be handled, and probably ignored as there's nothing you can do with the exception at that point.
Sending the minidump to you is another matter though, here's an article, you'll have to do some work to get it sent via email/http/ftp/etc.

Related

What is the cleaner way to handle exceptions [duplicate]

This question already has answers here:
.NET Global exception handler in console application
(5 answers)
Closed 9 years ago.
See this code:
try
{
int val = GenericLibrary.ConvertToInt(userInput);
return "Valid number";
}
catch (Exception)
{
return "Invalid number";
}
I writing a console application that has many try , catch block.I want to handle exception in cleaner way and follow DRY principle.
What is the best way for handle error in Console application c#?
Can I use Func or Action?
Can i use aspect oriented programming and how?
I want to clarify, cleaner - if you only want to write the error handling code in one spot then you could use AOP (eg PostSharp). But realise with error handlers via AOP they would then be compiled everywhere in your exe.
Also keep in mind this defeats the rule that exception handlers should be used exceptionally.
I'm not sure why you wrap a string cast to an int in a Try-Catch.
You could just handle unexpected exceptions in one place by setting up Global Exception handlers Application.ThreadException and AppDomain.CurrentDomain.UnhandledException. Remember to handle all the exceptions you expect such as the string to int cast.
You could use a Func for this cast but it would be easier with the simple method: Integer.TryParse.
What is clean does depend on a lot of factors. A general exception handler via PostSharp or other AOP handlers e.g. the Exception Handling Application Block from the Enterprise Library does even let you configure your policy. Although a nice idea it has never gained much traction until the policy injecion application block was in place which is also an AOP framework which would allow you to handle exceptions centrally in a configurable way.
However in reality exception handling remains hard. The first rule should be to never hide exceptions. You can catch them of course but you should always log them when you do not let them propagate further. What if your GenericLibrary uses some config file to decide in which locale the integers should be processed and it does not find its config file? You get repeated errors but you will never find out the root cause until you debug it because you throw away the exception object and return a string instead.
An equally bad "handling" strategy is to to
catch(Exception ex)
{
Log("Error has occured: {0}", ex.Message);
}
This will give you the error messsage but you loose the complete call stack and any inner exceptions. This is especially bad if you receive some generic wrapper exception like TargetInvocationException which contains only a generic error message.
The right handling strategy depends quite much on your specific context. If you mean with console application a small application which is not delivered to customers then it is usually the simpliest to remove all catch handlers in a first pass and handle them globally in the main method. Then when you have got experience with the most common non fatal errors you can re add the necessary catch handlers to regain robustness. Now you continue to work on non fatal errors but you keep the failfast strategy for the fatal ones.
Any previous answer here does only give you the advice to use this or that strategy but you need to decide which exceptions are non critical to your app on a case by case basis. When you catch everything you won´t find out why your app did nothing because of internally catched errors. If you have no handling at all your app will terminate on every non fatal error (e.g. it can be ok to return 0 if the value cannot be parsed in your app).
For a small console app I would
Remove all catch blocks
Even in the Main method
This way you get automatic logging of the .NET Framework in the application event log with no extra effort if your app does crash. If your console app is executed e.g. as a scheduled job printing the output to the console will not help you much. This is the cleanest way of handling exceptions: No handling at all and let your application crash so you can find out what went wrong in the application event log.
If you deploy besides your executable the pdbs for release builds you also get the line numbers and file infos which makes it really easy to spot the error in most cases.
If your application is mission critical or delivered to customers it can happen that you
need to employ some logging framework to log to some private log file. The difference between a console application and a windows application is only a flag in the PE header.
A Windows application will detach from the currently started console whereas a console application will remain attached to it. That is the only difference. You can also create a WPF application in a console application but it will block your console as long as it will run which is perhaps not the thing you did want.
But if you switch to a Windows application you can allocate a new console to make Console.WriteLine happen to work again and you can continue to use printf debugging which is perhaps the most used debugging method although a quite old fashioned one.
Usually you would add a tracing library to your application to follow your application flow which is by default off. Logging should also be done which is always on which does only error logging. With that approach you have more troublesshooting options at customer machines if error logging is not enough.
If you can want use Func see this:
You can use this
public static class SafeExecutor
{
public static T Execute<T>(Func<T> operation)
{
try
{
return operation();
}
catch (Exception ex)
{
// Log Exception
}
return default(T);
}
}
var data = SafeExecutor.Execute<string>(() =>
{
// do something
return "result";
});

Handling errors - should I use exceptions or events in an "event driven" application?

I am developing a small application that works like a script. I'll give it some urls and it will extract some useful info from them. As it is downloading the files and parsing the information, it's also raising events so that there's a listener, it will be able to read everything it wants.
The system is basically as follows:
class UrlInfoExtractor {
...
public void Run() {
...
}
...
}
As always, there's the risk of errors (i.e., there's no internet at the moment). At first I thought it would be good idea to have the Run() method throw some exceptions of my own (BadLoginException, BadUrlException, etc). But as there are already so many defined events, I came to think maybe it would be better to also have the errors pop up as events (I'm assuming that whatever error I get, I'll just stop the process). The whole approach to the system would be more.. consistent. On the other hand, it would allow errors to go unnoticed if the developers didn't care to listen to the error events.
Am I better using exceptions or raising events, in this situation?
If it is truly an error, I would raise an exception. The down side with using events is that if the caller does not add a handler for an exception event, they will not be notified there was an error and may assume that everything worked correctly.
If you are against raising exceptions, you could always return a status instead of your function being a void. That may allow you to avoid using exceptions for control flow, but you still have the ability to return information to the caller about the status of the call.
If you're going to stop your script or application anyway, I would suggest bubbling the exception up. You can catch and re-throw it wherever you need to clean up or save state. 'hiding' all your exceptions behind events is rarely a good idea.
If you're expecting exceptions often, john's suggestion on returning values instead of void will make for a cleaner in implementation if you intend to keep your script running.
As a sidenote, consistent doesn't necessarily equate to 'good'. Use language features for their purpose as far as possible.

System.Overflow Exception - int32 is too large or small

I need a little advice.
I've got windows service that runs at night. In my development environment, it runs without exception, but when I running it "installed on other machines", when I come in the morning, I'm welcomed with a System.Overflow exception that says that I've set an int32 to a value that is too large or small.
I've carefully combed the service's c# code, and I have try/catch statements around everything, that should catch any error and write it to a log without completely stopping my service with this overflow exception. But still, it occurs and stops the service.
I'd appreciate any conceptual advice on how to pin point what's causing an error such as this.
The problem with adding try/catch blocks throughout your code is it's easy to miss a place and hence not log the exception. A much more robust approach is to use the value AppDomain.UnhandledException. This will fire for any exception which is not handled within the current AppDomain. You can hook into this to write to your log file and hopefully get a better idea at where the error is coming form
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
...
void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
// Log the exception here
}
You must have missed an instance of try/catch or you have an error in your error handler or it would be handled.
In windows you can setup your service to restart if it ends unexpected manner.
First, let me tell you that overflow/underflow can be disabled, by opening project properties, selecting "Build" (from the left menu), and then "Advanced...".
By the way, I do it all the time, because it adds overhead, which I don't want in my scientific applications. Manually, then I control things.
But that does not solve the issues... It just hides the "problem", if it is a problem.
If you only care to check about a zero/non zero condition, somewhere in your code, disabling overflow at project settings solves the problem, because even when an overflow occurs you get a nonzero value, and your service continues without problems.
Also, for WinForms applications:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
And WPF:
http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx
To get visibility of exceptions on UI threads, since they're not forwarded to AppDomain.CurrentDomain.UnhandledException.

Long running App, how handle Errors?

i have to implement a Info Terminal. I choose dot.net and the terminal is only a touchpad.
So this System running 7 days 24 hours.
So i call a Webservice, display Data, show Website stuff. Many things can going wrong.
Have you some recommendations for this scenario?
Every function in an try catch? AppDomain.CurrentDomain.UnhandledException event?
Thanks Andreas
Basically, you should handle any error as soon as it is possible - so if you're calling webservice wrap all the calls in a try/catch block and handle the error there - you can, for example, log the exact error, aggregate many webservice-related exception in more generic, DataSourceFaultException (name is only for example), which will be then received by UI and UI will be able to easily determine, that it can't display requested info because communication failed, and choose to retry, notify user or do anything else.
However - with long running application there are many more errors you'll have to deal with. Many of them are not easy to predict, as they're not necessarily related to any specific call - you can run out of memory, a recursion might cause stack overflow, a system timer can reach it's max value and start from the beginning etc.
You shouldn't handle those errors in every method, as it will only hurt code readibility and will be error prone. Those errors are best handled by UnhandledException event. However, you must remember, that when the exception reaches UnhandledException event, you cannot assume anything about state of your application - the error might have corrupted some (or even all) of internal state. So when such condition occurs, it's best to try to create an error log and gracefuly restart the application (not necessarily whole application - maybe it will be possible to reinitialize application's state - if so, that's a valid option too. However, you must be aware that you won't be able to recover from some errors and handle such situation anyway).
It depends.
If you can handle appropriately an exception within a function - handle it. If not - create a global exception handler to inform user or log it.

Why are try-catch in main() bad?

Could someone explain to me why it is considered inapropriate to have a try-catch in the main() method to catch any unhandled exceptions?
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception e)
{
MessageBox.Show("General error: " + e.ToString());
}
}
I have the understanding that this is bad practice, but not sure why.
I don't think its necessarily bad practice. There are a few caveats however...
I believe the point of whoever called this "bad practice" was to reinforce the idea that you should be catching exceptions closest to where they occur (i.e. as high up the call stack as possible/appropiate). A blanket exception handler isn't typically a good idea because its drastically reduces the control flow available to you. Coarse-grained exception handling is quite importantly not a reasonable solution to program stability. Unfortunately, many beginner developers think that it is, and take such approaches as this blanket try-catch statement.
Saying this, if you have utilised exception handling properly (in a fine-grained and task-specific manner) in the rest of your program, and handled the errors accordingly there (rather than juist displaying a generic error box), then a general try-catch for all exceptions in the Main method is probably a useful thing to have. One point to note here is that if you're reproducably getting bugs caught in this Main try-catch, then you either have a bug or something is wrong with your localised exception handling.
The primary usage of this try-catch with Main would be purely to prevent your program from crashing in very unusual circumstances, and should do hardly any more than display a (vaguely) user-friendly "fatal error" message to the user, as well as possibly logging the error somewhere and/or submitting a bug report. So to conclude: this method does have its uses, but it must be done with great care, and not for the wrong reasons.
Well, this method will only capture exceptions thrown in your main thread. If you use both the Application.ThreadException and the AppDomian.UnhandledException events instead then you'll be able to catch and log all exceptions.
I don't see how that's bad practice at all.
Letting your program crash with an unhandled exception error isn't going to instill any confidence in your end users.
Maybe someone else could provide a counter view.
Update:
Obviously you'll need to do something useful with the exception.
log it
show the user a dialog stating WHY the application is exiting (in plain text, not a stacktrace)
something else that makes sense in the context of your application.
I don't think that's a bad practice in and of itself. I think the bad practice would be if that was the ONLY try/catch block you had in your application.
In antiquity, placing a try/catch in C++ caused a fairly heavy performance penalty, and placing one around main would mean storing extra stack info for everything, which again was bad for performance.
Now computers are faster, programmers less addicted to performance, and runtimes are better built, so it's not really bad anymore (but still you might pay a little more for it, haven't benchmarked it's effect in years). So it's old folklore like iterating against the grain (compilers actually fix the iteration anyways for you nowadays). In C# it's perfectly fine, but it'd look iffy to someone from 10 years ago.
Any exception which gets to Main() is likely fatal.
If it was something easy, it should have been handled higher up. If it was something beyond your control, like OutOfMemoryException, then the program should crash.
Windows application which crash have a standard way of doing so, they trigger the Windows Error Reporting dialog. (You've likely seen it before). You can sign up to recieve crash data when this happens.
I'm not sure I think its a bad practice. What you want to do is make sure that the exception and the current state of the program when it crashes ends up in the hands of a developer, preferably logged with date, time and the user who was working with it. Basically - you want to make sure that your team has all the information they need to debug the problem, regardless of whether or not the user goes to them about the crash. Remember that many users will not, in fact, contact support if they get a crash.
The bad practice here would be catching the exception, showing a simple "Error" dialog box, and closing the application. In that case, the state of that exception is lost forever.
From a debugging standpoint, this can make life more difficult, as it makes every exception a user handled exception. This changes the debugger's behavior, unless you break on unhandled exceptions, which potentially has other issues.
That being said, I think this is a good practice at release time. In addition, I recommend listening on the AppDomain.UnhandledException and the Application.ThreadException events, as well. This will let you trap even more exceptions (such as some system exceptions that will not be caught in your "global" handler above).
That allows you to log the errors and provide the user with a good, clean message.
Change it to this and it's fine
catch(Exception ex)
{
YourLoggingSystem.LogException(ex);
}
Of course, this line should NEVER be hit as you'll have other exception handlers throughout your code catching things with much more context.
Top-level exception handling is pretty essential, but I'd recommend using:
Application.ThreadException += new ThreadExceptionEventHandler(YourExceptionHandlingMethod);
However, this will only catch exceptions on the GUI thread (much like your try..catch block) - you should use similar code for each new thread you start to handle any unexpected exceptions from them.
More about it here.
You've got the catch-all exception there which will trap everything. So if you've got any unhandled exceptions in you code you'll never see them.
On the positive side, your application will never crash!
If this is required behaviour then you'll need to have sufficient logging and reporting to let both the user and you, as developer, know what's happened and recover or exit as gracefully as possible.
I'm not saying it's bad practice, the only thing I would do different though is use the built in event for that:
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message); //or do whatever...
}
I think this is discouraged because exceptions are caught only once and there may be multiple things, like background threads, that need to know if a process throws.
Is this a WinForms app? Forms.Application.Run raises events whenever a thread throws an unhandled exception. The MSDN docs try to explain this, but the handler they show doesn't work! Read the updated example from the WinForms UE site.
If your program tries to keep running despite a catch-all catching who-knows-what kind of violation of assumptions down below, it's in a danger zone for things like remote exploitation of security flaws (buffer overflows, heap corruption). Putting it in a loop and continuing to run is a big red flag for software quality.
Getting out as quickly as possible is the best, e.g. exit(1). Log and exit is good though slightly riskier.
Don't believe me? The Mitre Common Weakness Enumeration (CWE) agrees. Closely related is its advice against catching NULL pointer dereferencing in this way.

Categories