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?
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.
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.
You can use the AppDomain.UnhandledException event.
Maybe you want to use the Application.ThreadException event too.
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;
}
}
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
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
}
}
Related
I have following code.
try
{
int s=10;
int k=0;
int stdsd = s / k;
}
catch (DivideByZeroException ext)
{
FileStream fs = new FileStream(#"C:\temp\data.txt", FileMode.Open);
//encountered an exception as file doesn't exist.
}
catch (Exception ex)
{
}
finally
{
//some code here.
}
In above code when exception occured then it will try to write that in one file in catch block.but when it trying to open that file that file doen't exists, so in such cases system crashed. I want to execute such critical code in finally block but due to exception in catch block it not going further to that line.
I know we can check file exists check but I don't want to check file exist check over here, I want to how to manage that in catch block.
can please assist the best way to manage exception in catch block.
You can't handle the exception generated from one catch block in a catch block associated with the same try/catch statement. Instead, you need an extra one:
catch (DivideByZeroException ext)
{
try
{
FileStream fs = new FileStream(#"C:\temp\data.txt", FileMode.Open);
}
catch (IOException e)
{
// Handle the exception here
}
}
Note that you should be using a using statement when opening the stream, so that you'll close it automatically whether or not an exception is thrown later.
I'd also recommend not having the code like this in the catch block directly - typically catch blocks should be short, for readability. Consider moving all the error-handling functionality into a separate method (or possibly even a separate class).
Just use another try {} catch {} ...
try {
// ...
try {
// try opening your file here ...
} catch (Exception) {
// ...
}
} catch (Exception) {
// ...
}
If you don't want to check the existence of the file "over here" (in the exception), then you could alternatively check the existence "over there", that is: earlier in the code.
What you want to do is to write an exception log to a file, as I understand it. So you could configure the correct log file handling earlier in the code, in the best case with a good log file handler. After this the only thing you have to do within the exception handler is to push your exception message to the log handler - which will then write this information properly to the file.
exceptions are very powerful future of any language that can not be ignored in most cases , but try to avoid it if possible
Look at this
String File = "File.txt";
System.IO.FileInfo fileinfo = new System.IO.FileInfo(File);
if(fileinfo.Exists)
{
using (System.IO.FileStream file = new System.IO.FileStream(File, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite))
{
// operation on file here
}
}else
{
using (System.IO.FileStream file = new System.IO.FileStream(File, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
{
// operation on file here now the file is new file
}
}
I recently discussed with a coworker who told me that I was managing incorrently a stream into a try / catch / block. So I wanna know what would be a good approach for you.
try
{
StreamReader sr = new StreamReader("TestFile.txt");
//After that, here an operation of about 30 seconds to fulfill;
}
catch (IOException ioex)
{
throw new IOException("An error occurred while processing the file.", ioex);
}
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
finally
{
if(sr != null){
stream.Close();
stream = null;
}
}
He stated that having 2 Exception are unnecessary, even using the IOException. We can use only Exception. But the only thing that I want is to recognize where exactly the exception has been produced, because after opening the file, an operation of about 30 seconds will be performed.
So what would you think? We saw this MS example (http://msdn.microsoft.com/fr-Fr/library/system.io.streamreader.aspx) which it's simplier but in terms of performance or clean code, you find something strange?
Your opinions please!
-EDIT-----------------
Ok, I see the point but we were discussing about the Catch IOException and just using the Exception. In my opinion, like as in the example above you can know where the error ocurred; at the moment of managing the file or in the process after opening the file. That's my first question. And now, what do you think about this change below.
try
{
using(StreamReader sr = new StreamReader("TestFile.txt"))
{
//After that, here an operation of about 30 seconds to fulfill;
}
}
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
finally
{
if(sr != null){
stream.Close();
stream = null;
}
}
-------------------EDIT 2------------------------
Finally, I hope this would be my final solution. Thank you so much for your answers. So using is faster, efficient and just one exception is necessary.
try
{
using (StreamReader stream = sr = new StreamReader("TestFile.txt"))
{
//Operation
}
}
catch (Exception e)
{
throw new Exception(String.Format("An error ocurred while executing the data import: {0}", e.Message), e);
}
Any other comment would be appreciated!
you can use using block as below, and it will dispose the stream even on exception occurred
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
// do something with sr
}
Catch Exception if you're going to do something about. If you can't fix the problem, there's no point in catching it.
if you can't resolve the exception, it's best to just let the exception bubble up the exception and catch it there.
try
{
using(StreamReader sr = new StreamReader("TestFile.txt"))
{
// your code
}
}
catch (IOException ioex)
{
// do something to fix the problem
// log the exception
}
Don't catch an exception only to throw the same exception immediately, only now with less information and missing the stack frame of where the exception actually occurred.
If I came across something like
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
in a code review I would fail that review (not just for the grammar and spelling mistake either ;-)
At the very least, you should throw it with the original exception as an inner exception.
catch (Exception ex)
{
throw new Exception("A generic error occurred.", ex)
}
But to be perfectly frank, in this sample code it adds nothing whatsoever, it would be better removed entirely imo.
If you're rethrowing the exception instead of catching it, why bother creating a new exception? You're throwing away valuable information. There's literally no point in catching an exception only to throw it again. Nor is there any point replacing a helpful exception (as in, it's got all the diagnostic information anyone upstream might need) and replacing it with a generic exception.
For your situation, I'd simply:
using(var sr=new StreamReader())
{
//some code
}
all your other improvements are quite the opposite.
This question already has answers here:
Why is try {...} finally {...} good; try {...} catch{} bad?
(20 answers)
Closed 9 years ago.
difference between try...catch and try....finally ? in asp.net(C#)
like when i want to catch error like 1/0 then i put code in try block and put exception object in catch block like response.write("ERROR:"+ ex.Message) but advisors told me that it isn't a good practice to put catch always, it absorbs error without notifying ????? ehhhhh ? but it did via ex.Message , so why ?
and what does try....finally do ? i know that it is used to release resources but of what use is TRY if exception can't be catched ?
try/catch/finally:
try
{
// open some file or connection
// do some work that could cause exception
}
catch(MyException ex)
{
// do some exception handling: rethrow with a message, log the error, etc...
// it is not a good practice to just catch and do nothing (swallow the exception)
}
finally
{
// do some cleanup to close file/connection
// guaranteed to run even if an exception happened in try block
// if there was no finally, and exception happened before cleanup in your try block, file could stay open.
}
Try/Finally:
try
{
// open some file/connection
// do some work, where you're not expecting an exception
// or, you don't want to handle the exception here, rather just let it go to the caller, so no need for a catch
}
finally
{
// do cleanup, guaranteed to go in this finally block
}
Eveything that is enclosed in your finally block is ensured to be executed, and it could be useful in these 2 concrete cases at least :
Sometimes you decide to call return in the middle of your try block and get back to the caller : finally ease the process of releasing ressources here, you don't have to write some specific code to go directly to the end of your method.
Sometimes you want to let an exception go up (by not catching it) and maybe being caught at a higher level (because it is not the appropriate place to handle it properly for example). Again finally ensures your resources are released and the exception continue its path.
Maybe you can see finally as a tool helping developpers to do things they're obliged to do with less effort. On the other side, catch is dedicated to handle errors.
Both keywords are dedicated to flow control, but they don't have the same purpose and they can be used one without each other (and often are!). It depends on your needs.
Finally is always executed whether there is an exception or not. This can be handy if you want to be absolutely certain that something is cleaned up. Example:
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = #"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
// Do something with buffer...
}
If you didn't have a finally in there it would be possible that the file would not be closed properly if an error occurred. Regardless of whether an error occurs or not, you want the file to be closed when you are done.
Consider the alternative:
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = #"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
file.Close();
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
}
If you error out on ReadBlock the file will not be properly closed.
still giving problem
I have the following code. As long as I am in try { } it writes fine. But when there is an error, it doesn't write to log file. Not sure why
private static void jk(string kName, string path)
{
Job job;
try
{
// run some functions here and then write to the file
StreamWriter LJ = new StreamWriter("C:\\Lob.txt");
LJ.WriteLine("XXXXXXXXXXXX");
LJ.Close();
}
catch (InvalidException)
{
StreamWriter LJ = new StreamWriter("C:\\Lob.txt");
LJ.WriteLine("YYYYYYYYYYYYYYYY");
LJ.Close();
Console.WriteLine("Error: ");
return;
}
}
Because the only thing in your try is writing to the stream... and that's the same thing you try to do in the cacth. Why would that work?
The catch block executes only when the try block throws the exception (which appears to be a typo in the original post).
If the try succeeds, the catch is never executed.
If the try fails, it's because of a problem that must have occurred in writing to the log. When the catch executes, that problem most likely still exists, so the log within the catch will fail also.
Well, I don't know what type LJ is, and I certainly have never heard of a IncalidException. I am assuming that you just typed the code into the editor incorrectly. You should really just paste it in to avoid those types of errors.
Anyway, there are a few options:
LJ.WriteLine is not throwing an exception.
LJ.WriteLine is throwing an exception, but not of the same type you are catching (i.e., see if it works when you just catch { }).
The second call to LJ.WriteLine is also throwing an exception and you are catching (and perhaps swallowing) it further up the stack.
With your comment:
try fails because of some other problems but I am trying to log it
into the file
I assume that the exception is not thrown by LJ.WriteLine("XXXXXXXXXXXX");
If that's the case, you might just need to flush the StreamWriter. Try declaring LJ in a using block like this:
using (StreamWriter LJ = new StreamWriter("C:\\Lob.txt"))
{
LJ.WriteLine("XXXXXXXXXXXX");
try
{
...
LJ.WriteLine("XXXXXXXXXXXX");
}
catch (InvalidException)
{
LJ.WriteLine("YYYYYYYYYYYYYYYY");
Console.WriteLine("Error: ");
return;
}
}
Are you able to compile this code?
There are two things I see incorrect with the above.
It should be InvalidException not IncalidException
try
{
LJ.WriteLine("XXXXXXXXXXXX");
}
catch (InvalidException e)
{
LJ.WriteLine("YYYYYYYYYYYYYYYY");
Console.WriteLine("Error: {0}", e.Message);
return;
}
Simple best practice question.
Should you nest try catch statements or just use methods.
For instance, if you have a method that opens a file does work and closes the file, you would have the open and close outside the try catch, or rather the close in the finally block.
Now if your open method fails, the method would assert right? So should your wrap that in a try catch block or should that be called from another method, which in turn as a try catch block?
In the context of a method that opens a file I would use a using statement vs a try catch. The using statement ensures that Dispose is called if an exception occurs.
using (FileStream fs = new FileStream(file, FileMode.Open))
{
//do stuff
}
does the same thing as:
FileStream fs;
try
{
fs = new FileStream(file, FileMode.Open);
//do Stuff
}
finally
{
if(fs!=null)
fs.Dispose();
}
Now that we have lambdas and type inference and some other stuff, there's an idiom that is common in other languages which now makes a lot of sense in C#. Your example was about opening a file, doing something to it, and then closing it. Well, now, you can make a helper method which opens a file, and also takes care of making sure to close / dispose / clean up, but calls out to a lambda you provide for the "do stuff" portion. This will help you get the complicated try/catch/finally dispose/cleanup stuff right in one place, and then use it over and over.
Here's an example:
public static void ProcessFile(string filePath, Action<File> fileProcessor)
{
File openFile = null;
try
{
openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after.
fileProcessor(openFile);
}
finally
{
openFile.Close(); // Or dispose, or whatever.
}
}
Now, callers of this method don't have to worry about how to open the file or close / dispose of it. They can do something like this:
Helpers.ProcessFile("C://somefile.txt", f =>
{
while(var text = f.ReadLine())
{
Console.WriteLine(text);
}
});
This is a style question but for me I try to never have more than one level of try/catch/finally nesting in a single method. At the point you hit a nested try, you've almost certainly violated the 1 function = 1 operation principal and should use a second method.
Depends on what you are trying to do, but in most cases, nested try/catches are a sign of an over-complex function (or of a programmer who doesn't quite know how exceptions work!).
In the case of the open file, I'd use an IDisposable holder and a using clause, and so forgo the need of any explicit try/catch.
How about where you have related code that doesn't necessarily belong in a separate function of it's own right? Would this then be correct?
try
{
// Part 1 Code Here
try
{
// Part 2 Code Here
}
catch (Exception ex)
{
// Error from Part 2
}
}
catch (Exception ex)
{
// Error from Part 1
}
Most of the time I would break up the nested try/catch blocks into functions. But I have sometimes written code to catch and log all uncaught exceptions thrown by my application. But what if the logging code fails? So I have yet another try/catch around that just to prevent the user from seeing the default .NET unhandled exception dialog box. But even this code could very easily be refactored into functions instead of nested try/catch blocks.
try
{
try
{
DoEverything();
}
catch (Exception ex)
{
// Log the exception here
}
}
catch (Exception ex)
{
// Wow, even the log is broken ...
}
//create a switch here and set it to 0
try
{
DoChunk1();
//looks good. set the switch to 1
}
catch (Exception ex)
{
// Log the exception here
}
// check the switch, if it is still zero at this point then you may halt your program here; else set the switch back to zero and execute your next try catch statement. totally agree with breaking them down as mentioned above
try
{
DoChunk2();
//looks good. set the switch to 1
}
catch (Exception ex)
{
// Log the exception here
}
try
{
----
}
catch
{
try
{
---
}
catch
{
---
}
}