Daltons
Daltons

Reputation: 2711

Handling of unforseen exceptions

If I want to write to a file and handle IOExceptions (in case the file is write-protected), I would do the following:

try
{
    var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)
    {    
        sw.WriteLine(entry);
    }
}
catch (IOException ex)
{
    return ex.Message;
}

If I get an unexpected exception my program will crash, the user will report the bug and I will fix it. That is what I want.

So should I add another catch like:

catch (Exception)
{
    throw;
}

Will this make any difference and what is the best practice?

Upvotes: 4

Views: 123

Answers (6)

Chris Mantle
Chris Mantle

Reputation: 6683

You should handle unexpected exceptions, but a catch with a throw is redundant - the exception is thrown out of your method anyway. What you should do is ask yourself the question, "What can I do about this exception here?". For IOException, the answer is clear. You expect that exception could occur, can handle it, and can continue. In the case of a generic Exception, this may not be the place to handle it.

If you need to run some code when an exception occurs, add a catch for it. If your code cannot continue after that exception, throw the exception higher (by not handling it or using throw), and add handlers higher up in the call hierarchy. Maybe it can be handled at a higher level, and execution can continue. If not, your application will need to exit.

You can add a top-level try/catch block in your program's entry point, and catch unhandled exceptions there. Your application may even be able to continue after this (however, it's unlikely in any non-trivial application, given how high the exception will have been thrown at that point). To catch any other unhandled exception (those that are unhandled in threads, for example), you can add a handler to AppDomain.CurrentDomain.UnhandledException. However, this is unrecoverable - your application will exit directly after. The UnhandledException handler is the last chance to do something with an exception before that happens, usually logging it to diagnose what went wrong.

Oh, also, if you're writing a WPF application, you can add a handler in your App.xaml for the DispatcherUnhandledException event on Application. That catches any unhandled exceptions that occur in the WPF dispatcher thread. Unlike the AppDomain handler above, unhandled exceptions on the dispatcher thread can be continued from - you can set IsHandled in the event args to true if it's OK for the application to continue.

Upvotes: 3

jgauffin
jgauffin

Reputation: 101150

So should I add another catch like

(almost) Never. At least not down in the stack trace. It will just make your application harder to read.

Most applications have entry point. For instance if you writing a windows service you typically create threads for the work. You can have a catch (Exception) in those to prevent them from crashing.

So what I'm saying is that you should in most cases only use catch all in the top layer to prevent your application from being harder to read or maintain.

When everything fails

Sometimes your application will crash anyway if you have forgot a catch all somewhere in the top layer.

You then want to use AppDomain.UnhandledException as it's invoked in for all application types in .NET. It will however not let you prevent the application from crahsing but just to log why your application is about to crash.

If you are coding UI applications based on winforms you can use the Application.ThreadException instead. However, it will only handle exceptions on the UI thread. Hence you still need to use the AppDomain.UnhandledException to log exceptions thrown on other threads.

All major library/framework in .NET have it's own way to allow you to handle unhandled exceptions. You need to look it up in the documentation of the library that you are using.

Upvotes: 1

Max
Max

Reputation: 156

hi if you want to throw exception that the application will crash do this

 try
{
    var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default)
    {    
        sw.WriteLine(entry);
    }
}
catch (IOException ex)
{
    throw ex;
}

but in my opinion you should not let it crush but only show the error message

in the catch call function write to file and then return the message and show to user . hope it helps

 public static void WriteCustomLog(string msg)
            {
                FileStream fs = null;
                StreamWriter sw = null;
                FileStream fs1 = null;
                StreamWriter sw1 = null;
                try
                {
                    //check and make the directory if necessary; this is set to look in the application
                    //folder, you may wish to place the error log in another location depending upon the
                    //the user's role and write access to different areas of the file system
                    if (!System.IO.Directory.Exists(Application.StartupPath + "\\Log\\"))
                        System.IO.Directory.CreateDirectory(Application.StartupPath + "\\Log\\");

                    string date = DateTime.Now.ToString("dd_MM_yyyy");

                    //check the file
                    fs = new FileStream(Application.StartupPath + "\\Log\\Log" + date + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    sw = new StreamWriter(fs);
                    sw.Close();
                    fs.Close();

                    //log it
                    fs1 = new FileStream(Application.StartupPath + "\\Log\\Log" + date + ".txt", FileMode.Append, FileAccess.Write);
                    sw1 = new StreamWriter(fs1);
                    sw1.Write(DateTime.Now.ToString() + " Message: " + msg + Environment.NewLine);
                    sw1.Write("Date/Time: " + DateTime.Now.ToString() + Environment.NewLine);
                    sw1.Write("=======================================================" + Environment.NewLine);

                }
}

and then dispose the objects was not tested

Upvotes: 0

James
James

Reputation: 9975

catch(Exception)
{ 

    throw;    
} 

does nothing. The exception is thrown with it's original stack trace and no additional actions are performed. You could catch general exceptions, which gives you the option to provide additional logging and/or present the user with a nicer error message

catch(Exception ex)
{ 
    LogError(ex);
    if (weDontCareThisWasntImportantAnyWay)
    {
        if (theUserShouldBeNotifiedAtThisPoint)
        {
            SomehowNotifyTheUser(ex);
        }
    }
    else
    {
        //Maybe something else cares
        throw;    
    }
} 

Upvotes: 0

Gargo
Gargo

Reputation: 711

You can use the AppDomain.UnhandledException event.

Maybe you want to use the Application.ThreadException event too.

Upvotes: 0

mjroodt
mjroodt

Reputation: 3313

You could catch the exception and then inside check what type the expception is. Then decide how to handle it.

catch(Exception ex)
{
  if(ex.InnerException is IOException )
  {
    // do  something
  }
 else
  {
   // do something else
  }
}

Upvotes: -1

Related Questions