Reputation: 2711
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
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
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
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
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
Reputation: 711
You can use the AppDomain.UnhandledException event.
Maybe you want to use the Application.ThreadException event too.
Upvotes: 0
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