Give user option to send error-report on uncaught exception - c#

I've developed an application used by a third-party company.
Since I'm a horrible coder the application does still have some bugs which causes it to crash (unhandled nullpointerexception for example).
It's a Windows-forms application running on .NET 4.5 and now they are just getting the classic "An unhandled exception caused the app to terminate, press details for more info".
Trying to convince them that pressing "Details" and sending the stack-trace to me is really useful but they all seem reluctant.
Would it be possible to automate this behaviour, like show them a custom global "Exception catcher" where they can just press a button to send it to me by E-mail.
Inbefore "Global exception handling is bad" and "Why does your application throw nullpointerexceptions, you are a bad coder etc."
BR Tomas Anyuru

I guess the exceptions you get are unhandled.
Because of this, you will have to use the Application.ThreadException event to handle them. Because there is no .NET automatic mail sending and message display, you will have to implement your own inside this event.
Please have a look of an answer I wrote to have some examples of Exception catching strategies.

wrap your whole main() function in try-catch statement.
this way any un-handled exception will roll back and will be catched in your catch block:
static void main()
{
try
{
// the application code...
}
catch (Exception ex)
{
DialogResult result = MessageBox.Show(
"Some error occured, please click ok to send it to the develpoer");
if (result = OK)
email(ex); // this is your function to send the email.
// useful information is also in ex.message
// here program will exit without error!
}
}

you can use log 4 net it is open source logging tools, use a lot by Java developer, and this version is specially for .Net http://logging.apache.org/log4net/

In addition to #Shamim code, you can wrap your main function in try, catch block, since the catch block here will track down the exception occurred inside any function called in the try block.
Shooting a mail inside catch block sometime throws and exception about Thread abort, so finally would be the right place to do so :
catch (Exception err)
{
mailBody = "Error: " + Convert.ToString(err.Message) + "<br /> Source: " + Convert.ToString(err.Source);
//Can display some message to user in an Literal Control from here.
}
finally
{
if (!string.IsNullOrEmpty(mailBody))
{
mailObject.To.Add(mailTo);
mailObject.CC.Add(mailCc);
mailObject.Body = mailBody;
MailService(mailObject);
}
}
MailService is a method to send mail which accept a MailObject as parameter.

Related

Best practices for throwing exceptions that are to be displayed to the user

Unexpected exceptions that should terminate execution of the program are simply thrown. They are caught by CurrentDomain_UnhandledException and taken care of there - logged if necessary, and a generic "This app is about to crash and you have nothing to do about it" message displayed to the user.
But what about those exceptions that only need to cancel an operation, while showing the user a more useful message? e.g. informing the user that a file can't be accessed because it's being used by another process. This exception might be deeply nested, and I wouldn't want to check for some flag at every method return. I'd rather have something like this: when the user initiates the most "external" method - say, a button click event handler, the code will include a try-catch block catching all DisplayToUserException's , and rethrow any other exceptions. So I'll have to create this custom exception class.
But before I go down that path, I'd like to know if that's the standard thing to do, or perhaps there's a better solution for this. Or perhaps a class already built for this. Hence this question.
It's ok to put a try/catch block around your UI events:
public void Button1_Click(object sender, EventArgs e)
{
try {
// Do something interesting, like calling methods that throw (nested) exceptions
// Maybe these methods do file I/O
}
// Though it's better to catch a more-specific exception or set of exceptions
catch (IOException ex){
MessageBox.Show(ex.ToString());
}
}
This limits the effects of the exception to the UI operation (the button click, in this case).
A truly unhandled exception, one that you can't anticipate or do anything about, will still get handled by the AppDomain exception handler.
Note also that the Message property of an exception is meant for display to the user. It's ok to catch a "technical" exception, and rethrow as an exception with a user-friendly message. But be sure to include the original exception:
try {
// Do something with the file name in the <c>path</c> variable
}
catch(IOException ex){
throw new InvalidOperationException(
String.Format("Can't perform that file I/O on {0}, sorry about that", path), ex);
}

modifying existing program to handle exceptions better

I'm working on an existing C# program that queries and makes changes to various resources outside of the program and computer that the program is run on. The program works on most computers but randomly fails on random computers every so often. When this happens we have no feedback as to why other than what the user tells us about the exception that was thrown up on the screen that they may or may not have already cleared. Even if they leave it up on the screen for us it provides little to no useful information to us. I have since modified the program to log particular events and gathered information to a text file that I can use to approximate where the program stopped. This is at least a start but from reading many threads on stackoverflow.com as well as other forums I know that the program needs to at least make an attempt to handle the specific exceptions that could come up when querying and modifying LDAP, DS, DNS, SQL and so on.
Currently there is just big try blocks surrounding all of the to do code with just one catch block at the end of each.
private void method_name()
{
try
{
//many lines of to do code calling many other methods
}
catch (exception ex)
{
MessageBox.Show("An Error has occurred in method_name() :" + ex.Message);
}
My first thought was to nest more specific try/catch blocks within the larger try blocks but I keep running into problems with variables becoming unreachable in different contexts. for example
try
{
LdapConnection ldapConn = new LdapConnection();
ldapConn.Connect(details of connection);
ldapConn.Bind(details of bind statement);
LdapSearchQueue queue = ldapConn.Search(search criteria and such);
LdapMessage message;
}
catch (somesortofexception ex)
{
//do something sensible about it
}
while ((message = queue.getResponse()) != null)
{
//do things with message
}
ldapConn.Disconnect();
the problem being that message and queue are unreachable outside of the try block. This is just one example of something done withing the "//many lines of to do code calling many other methods" that I'm trying to work with.
So here are my questions:
Would it be better to try and make the try block bigger in the above example to include the while loop and ldap disconnect or to just leave the big try loop, make a list of things that happen during that and create many catch blocks at the end to catch specific exceptions? I feel like putting in the smaller try blocks around specific code is the way to go based on what I've read on this site.
Should I use the smaller try blocks like I've been trying to implement, would be be okay to just use a catch block that catches any exception raised within that small snippet of code and log it to my log file or should I try and catch specific exceptions? I don't really have anything different I can do with those exceptions other than log them to the file anyways.
Do I need to throw the exceptions? I don't really want anything bubbling up to the user other than a message in plain english saying that something went wrong and to contact IT. Currently none of the catch blocks throw anything.
About breaking down exceptions, I would always separate the connection code from the query one.
So this would become:
LdapConnection ldapConn = new LdapConnection();
try
{
ldapConn.Connect(details of connection);
ldapConn.Bind(details of bind statement);
}
catch (somesortofexception ex)
{
//Log, send error message..
ldapConn = null;
}
if (ldapConn != null)
{
try
{
//Do what you need with your connection
}
catch (Exception ex)
{
//Log, Error....
}
finally
{
//Disconnect your ldap here
}
}
Ideally i would put all the connection code and search code in separate methods as well,
so you'll have some nicer stack trace.
About error message I would also just use some generic message and log exception specifics into some kind of file ( http://logging.apache.org/log4net/ ) is quite nice for having nicely formatted log files.
A local catch block that swallows a specific exception is fine as long as you're expecting that exception and it can be handled locally. In this case you can provide information to the user based only on what the exception contains, or you can move the variable definitions above the try block if you want to include their state in the logging and/or message.
For exceptions that you're not expecting, you should let them bubble upwards to the top of the call stack where they can be logged by a global handler before exiting the program gracefully. You don't want to potentially nail the corpse in an upright position by swallowing these exceptions.
Assuming this is a WinForms app, the setup of global handlers looks something like this:
public static void Main(string[] args)
{
// Switch-off the Windows Forms default handler for unhandled exceptions.
// NB From .NET 4 upwards, this won't work if the process state is corrupted.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Setup event handler to intercept an unhandled exception on a UI thread.
// NB The exception will still terminate the application.
// But you can show a MessageBox and/or log the exception.
Application.ThreadException +=
new ThreadExceptionEventHandler(App_UiThreadException);
// Setup event handler to intercept unhandled exception on a non-UI thread.
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(App_NonUiThreadException);
// Run the application (open main form etc).
}

How to catch exceptions

This is my first application that will deal with exceptions properly. It's a WCF service. All the other before were simple apps just for myself. I have very small knowledge about exception handling in C#.
I have a code like this:
MembershipUser memUser = Membership.GetUser(username);
DatabaseDataContext context = new DatabaseDataContext();
UserMembership user = UserMembership.getUserMembership(memUser);
ItemsForUser itemUser = Helper.createItemForUser(ref item, memUser);
Helper.setItemCreationInfo(ref item, user);
context.Items.InsertOnSubmit(item);
context.SubmitChanges();
In this code a few exceptions can happen. Like NullReferenceException for example. How do I know which object caused the exception so I can know what to do in the catch and what to return to the client?
In general, you should not catch any exceptions.
I know this sounds strange, but the fact is that you should only catch exceptions you can actually do something about, and you usually can't do anything about exceptions.
The "exceptions" to this rule have to do with what it means to "handle" an exception. In some applications, "handling" the exception means to log it. In others (ASP.NET, for instance), it's better to not handle the exception, because the framework (ASP.NET Health Monitoring in this case) will log it for you.
In event-driven code, like Windows Forms, I find it's necessary to catch exceptions within event handlers. At least in earlier versions of .NET, allowing the exception to propagate outside of, for instance, a button click event produced unpleasant results. I typically catch the exception and display it in a dialog box.
In a multi-tier application, one might catch exceptions on tier boundaries, then rethrow a new, tier-specific exception:
try
{
// ...
}
catch (Exception ex)
{
throw new TierException("Some message", ex);
}
Another use case is to catch the exception, then throw a new exception with more information in it:
public int GetValueFromConfigurationFile(...)
{
const string configFileName = "...";
try
{
// ...
}
catch (FileNotFoundException fEx)
{
throw new InvalidOperationException(
String.Format("Can't find configuration file {0}", configFileName),
fEx);
}
}
In this case, you are catching a specific exception (FileNotFoundException), and providing your caller information they could not otherwise know: that the file not found was a configuration file.
The general message is:
- Only catch exceptions you know how to handle
- Catch the most specific exception possible
- Always include the inner exception when creating a new exception, to preserve the chain of exceptions
- To rethrow the current exception, use throw;, not throw ex;
There are a few more, and I'll try to find you the reference from the Microsoft Framework Design Guidelines.
P.S. If someone can find the question this is a duplicate of, feel free to close as a duplicate. I don't mind losing any rep from this. I just couldn't find the duplicate.
I should have just posted the link to the "exception-handling" tag wiki, where it says:
However, for exception handling in the context of .NET programs, see
"Design Guidelines for
Exceptions".
Although WCF has mechanisms for passing server exceptions through to the client it is probably worth considering if your client user really wants to see typically complex server side exceptions in their face.
In general better to trace server side expections - and if you want access to that remotely then use a remote tracing logger. Or have a single text trace api on your server to log server exceptions client side in an unobtrusive fashion.

Exception handling within an Exception in C#

i know this could be a little weird but a doubt is a doubt afterall...
what would happen in the following situation...
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
//so i will handle that exception over here
//and since an exception occurred while sending a mail
//i will log an event with the eventlog
//All i want to know is what if an exception occurs here
//while writing the error log, how should i handle it??
}
}
Thank you.
I would personally wrap the call to write to event log with another try\catch statement.
However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.
You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
WriteToLog();
}
}
private void WriteToLog()
{
try
{
// Write to the Log
}
catch(Exception ex)
{
// Error Will Robinson
// You should probably make this error catching specialized instead of pokeman error handling
}
}
Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.
You could add a try-catch block in your catch block as well.
Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...
Let it bubble up and be handled by an upper level try/catch.
Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:
disposing of the contents of your mail object
making sure your socket is closed
writing an entry into your log file to note the error
Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.
I personally handle this situation using a simple extension method.
public static class MyExtentions
{
public static void LogToErrorFile(this Exception exception)
{
try
{
System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
}
catch
{
// Handle however you wish
}
}
}
The usage is simple:
try
{
...
}
catch(Exception ex)
{
ex.LogToErrorFile();
}
You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.
Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.
For exceptions that have no control over, use global handling exception, like Application_Error for web.
Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.
Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.
Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg
and
Documenting Exceptional Developers By Peter A. Bromberg
For web application look into
Health monitoring
Exception logging
One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.

C# Returning something from exception handle

I have the following code in a class of mine. The purpose of this class is to get the balance from a web server. Just in case something goes wrong with getting the balance. I will handle a exception. However, all this is easy to do. But I am left wondering what do I return in my catch statement.
Most of the examples I looked at just write to the console using:
Console.WriteLine(ex.Message);
That is all very well. But in a real application what do most developers do?
//Download only when the webclient is not busy.
if (!wc.IsBusy)
{
// Sleep for 1/2 second to give the server time to update the balance.
System.Threading.Thread.Sleep(500);
try
{
// Download the current balance.
wc.DownloadStringAsync(new Uri(strURL));
}
catch (WebException ex)
{
Console.Write("GetBalance(): " + ex.Message);
}
}
else
{
Console.Write("Busy please try again");
}
My function at the moment returns void. And I am just wondering what else I would return if the webclient is busy?
Many thanks for any advice,
Do not catch an exception if you cannot handle it. If you return just some value, the calling method has to check if the value is a real result or just an indicator of an exception. And now this method must decide what to do and return. And the method calling this method. And the method...
So just let the exception bubble up the stack and catch it somewhere where you can handle it. Maybe directly below the user interface and then display a message box asking if the user wants to retry or display information how to solve the problem. If you have no user interface, catch it somewhere where you can solve the problem and retry. If it is a temporary problem, retry the whole task at a reasonable level until the call succeeds.
If you want to log something, use the following pattern to log the exception an rethrow it.
try
{
DoStuff();
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
Note that it is throw; and not throw exception;. If you do the later, you lose the original stack trace. If you can infer more details about the cause of the exception, you should wrap the caught exception into a more meaningful exception with additional information.
try
{
DoStuff();
}
catch (SpecificMeaninglessException exception)
{
Log(exception.ToString());
throw new MeaningfulException("Details about the error.", exception);
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
You should use ex.ToString() method
Exception.Message
contains a simple description of the exception (e.g. "Object reference not set...").
Exception.ToString()
contains a description of the exception along with a complete stack trace.
Exception Handling Best Practices in .NET
You could re-run the method if the client is busy but wait a certain time before retries? Potentially with a failure after x retries.
If instead you wish to move on and simply log the problem, your catch statement could log the exception to a file-based log, event viewer, submit to a database, raise an alert (email, sms etc.) if it is necessary.
Depends on the severity of the exception.
I would suggest looking into The Exception Block from Patterns & Practices
If you're only interested in viewing the exception you should re throw the exception so who-ever is planning on handling it will still get it.
You certainly don't want to mask an unhandled exception. Let that bubble up through the stack. But if you are asking what to return if the web client is just busy, how about
returning either a random interval or some meaningful interval that the function caller should wait before attempting to download the balance again? A random number could distribute load or otherwise mitigate a collision problem. A more meaningful interval could be sent back based on the the current state of the server.

Categories