How to efficiently manage a Stream with try / catch / finally C# - c#

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.

Related

How to manage exception in catch block c#?

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
}
}

Finally block in try/catch not working?

Ok, as far as I understand, try/catch blocks try an operation and catch blocks catch exceptions. The more specific exceptions go up top, the more generic towards the bottom of the series of catch blocks. In the following code, I implement try/catch, everything works fine.
As far as I understand, a finally block always executes. Some people have argued that there is no purpose to finally block, because if there is an exception or there isn't, the code after the last catch block gets executed anyways.
However, the argument against this is that if there is an exception thrown in a catch block, there are no subsequent catch blocks to catch that exception. So by putting resource cleanup code in a finally block, you ensure that resources will be released in the event that an exception is thrown in a catch block.
Which is why the following code puzzles me. I throw an exception in the first catch block and the finally block never executes. Why?
*Please note that there is indeed an exception thrown while creating myStreamReader, as the file is actually called generic.txt and is misspelled with purpose, in order to throw the initial exception.
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreadReader.ReadToEnd());
}
catch(FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw new Exception();
}
catch(Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
if(myStreamReader != null)
{
myStreamReader.Close();
}
Console.WriteLine("Closed the StreamReader.");
}
VIDEO:
The issue with this block of code originates in this video, at the 27:20 mark:
https://www.youtube.com/watch?v=WxdSb3ZCWYc&list=PLAC325451207E3105&index=41
The guy directly declares that an Exception that occurs in a catch block will not prevent the finally block from executing. I am seeing that it does.
If that new exception is completely unhandled, the entire process is torn down, and the finally block never gets to run.
If there's some other exception handler at a higher level, or an unhandled exception handler has been installed, the finally block does run.
This sample does show "Closed the StreamReader":
static void Main()
{
try
{
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreamReader.ReadToEnd());
}
catch (FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw new Exception();
}
catch (Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
if (myStreamReader != null)
{
myStreamReader.Close();
}
Console.WriteLine("Closed the StreamReader.");
}
}
catch
{
}
Console.WriteLine("Done");
Console.ReadLine();
}
Unhandled exception handlers can be registered in the AppDomain.UnhandledException event.
Your understanding is not correct. See try-finally.
By using a finally block, you can clean up any resources that are
allocated in a try block, and you can run code even if an exception
occurs in the try block. Typically, the statements of a finally block
run when control leaves a try statement. The transfer of control can
occur as a result of normal execution, of execution of a break,
continue, goto, or return statement, or of propagation of an exception
out of the try statement.
So finally does executed if you return for instance out of a try block, but not if you throw from a catch block.
However, if the exception is unhandled, execution of the finally block
is dependent on how the exception unwind operation is triggered. That,
in turn, is dependent on how your computer is set up.
Assuming the file is not found, it would first catch the FileNotFoundException:
catch(FileNotFoundException error)
{
Console.WriteLine(error.Message);
Console.WriteLine();
throw new Exception();
}
This writes a message to the console, and then throws a new Exception. This exception however, is unhandled and will halt execution. If you throw an exception from within a Catch block, it will not be caught by any subsequent blocks.
The solution is to handle the exception appropiately instead of throwing a new one. If the file was not found, then act upon it, e.g. let the user choose another file, create the file, etc.
use throw instead and try this. When you throw a new exception, the actual exception will be lost. But when you use just throw it will throw the actual exception which is FileNotFoundException.
StreamReader myStreamReader = null;
try
{
myStreamReader = new StreamReader("c:\\genneric.txt");
Console.WriteLine(myStreadReader.ReadToEnd());
}
catch(FileNotFoundException Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
throw;
}
catch(Exception Error)
{
Console.WriteLine(Error.Message);
Console.WriteLine();
}
finally
{
Console.WriteLine("Closing the StreamReader.");
try{
if(myStreamReader != null)
{
myStreamReader.Close();
}
} catch(Exception e) { Console.WriteLine(e.ToString()) };
}
}

why doesnt it write to file in exception

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;
}

How do I catch and ignore or handle an exception while reading data from a text file line by line

I am reading a file line by line from text file and do some processing. The problem is that if some error occurs at some line. Then an exception is generated, what I want is that I want to ignore that error and move to the next line to read.
But if an exception is generated then I cant continue reading input lines. Please help.
If I'm assuming what you're asking for correctly, here's a basic outline of what your code could look like:
using (StreamReader reader = File.OpenText("Path\to\your\file"))
{
string line = null;
while ((line = reader.ReadLine()) != null)
{
try
{
ProcessLine(line);
}
catch { /* Ignore exceptions */ }
}
}
It's generally not a good idea to blindly catch all exceptions, so if you can, you should filter the exceptions caught by your catch block to something more specific.
See exception handling. http://msdn.microsoft.com/en-us/library/0yd65esw(v=vs.71).aspx
If you really want to "ignore" exceptions, you can do something like:
try
{
foo(); // Something that may throw an exception
}
catch
{
}
See http://msdn.microsoft.com/en-us/library/0yd65esw(v=vs.80).aspx for more info.
But usually, an exception means something bad happened, and you'll probably want to handle that somehow.
try
{
//put the statement throwing the exception here
}
catch
{
//will eat the exception
}
//execution will continue here
Difficult to understand what you want to achieve, but you probably are asking for something like this:
while(condition)
{
try {
//process file line here
}
catch (Exception ex) {
LogException(ex);
}
}
Not a good design decision in my opinion, by the way. Avoid it if you can.
Use a try catch and log the error. Your code would look like this:
try
{
//read lines here
}
catch(Exception ex)
{
//log the exception but don't throw anything.
}
You may be tempted to do nothing in the catch, but you will likely regret it later.
Try catch article:
http://www.homeandlearn.co.uk/csharp/csharp_s5p6.html
You simply need to wrap your processing code in a try / catch block.
try
{
DoSomeProcessing(lineThatIreadFromFile);
}
catch
{
// Log or Ignore error here
}
However, please note that typically, just swallowing exceptions is never a good idea. You should either fail your program (if unrecoverable), or potentially log those somewhere so you can fix why your program is failing.
Based on the very limited information you provide there are two things you can do:
Enclose the offending line with an empty catch block. Wait for next maintainer to do bad things to you.
Understand why the exception is happening and modify the code such that the next maintainer understands why it is safe that you ignored a certain condition
This is not a good approach. You should be proactive and catch specific exceptions you can recover from. Catch them as close to the place where they are thrown from. And let the rest of them bubble up and terminate the process. By swallowing all exceptions you will get an illusion of robustness while in fact your code may be full of bugs. There is simply no 'quick and dirty' approach to exception handling. See this answer.
Avoid handling errors by catching non-specific exceptions, such as
System.Exception, System.SystemException, and so on, in application
code. There are cases when handling errors in applications is
acceptable, but such cases are rare.
An application should not handle exceptions that can result in an
unexpected or exploitable state. If you cannot predict all possible
causes of an exception and ensure that malicious code cannot exploit
the resulting application state, you should allow the application to
terminate instead of handling the exception.
You need:
using System.IO;
to get this to work.
You can try:
try
{
string path = ""; // You must add the path here. Else it won't work.
string[] lines = File.ReadAllLines(path);
foreach(string line in lines)
{
Console.WriteLine(line);
}
} catch (Exception ex, IOException ioex) {
// It's optional. You can remove "Exception ex, IOException ioex" if you want. You can delete the code below too.
Console.WriteLine(ex.ToString());
Console.WriteLine();
Console.WriteLine(ioex.ToString());
} finally
{
// in this "finally" section, you can place anything else. "finally" section isn't important, just shows that method has no exceptions.
// you can add something else like: Console.WriteLine("Code has no exceptions. Great!");
}
Good for advanced notepads.
EDIT: If you don't like the previous solution, this one can help you.
string path = ""; // Again, path.
string[] lines = File.ReadAllLines(path);
foreach(string line in lines)
{
try
{
Console.WriteLine(line);
} catch(Exception ex, IOException ioex)
{ /* exception */ }
}
----- or -----
string path = Console.ReadLine();
int turns = 0;
int maxturns = (File.ReadAllLines(path)).Count();
while (turns < maxturns)
{
try
{
Console.WriteLine(File.ReadLines(path).Skip(turns).Take(1).First());
} catch (Exception ex, IOException ioex) { /* exception */ }
turns++;
}

The mystery of the twin exceptions

Here's an interesting question. I have a system that attempts to run some initialization code. If it fails, we call the deinitializer to clean everything up.
Because we call the deinitializer in exception handling, we run the risk that both initialize and deinitialize will fail, and hypothetically, it now seems that we have to throw two exceptions.
It seems pretty unlikely that we will, though. So what happens and what should the code do here?
try { /* init code here */ }
catch (Exception ex)
{
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
throw new OCRException("Engine failed to initialize; ALSO failed to deinitialize engine!", ex2);
}
finally
{
throw new OCRException("Engine failed to initialize; failed to initialize license!", ex);
}
}
You shouldn't throw in the Finally block. Instead, use the InnerException to add information in the throw.
Update
What you have to do is to catch and rethrow with the "history" of exception, this is done with InnerException. You can edit it when bulding a new exception. This is a code snippet I just wrote to illustrate the idea that I explain in all the comments below.
static void Main(string[] args)
{
try
{
principalMethod();
}
catch (Exception e)
{
Console.WriteLine("Test : " + e.Message);
}
Console.Read();
}
public static void principalMethod()
{
try
{
throw new Exception("Primary");
}
catch (Exception ex1)
{
try
{
methodThatCanCrash();
}
catch
{
throw new Exception("Cannot deinitialize", ex1);
}
}
}
private static void methodThatCanCrash()
{
throw new NotImplementedException();
}
No need to use double throw with finalize. If you put a break point at the Console.WriteLine(...). You will notice that you have all the exception trace.
If your clean up code is failing and you cannot leave the application in a clean and known state I would let the exception go unhandled (or catch it with the UnhandledException event to log it) then close the application.
Because if you can't handle the first exception, what point is there in catching the second exception?
If I understand your problem correctly, here's what I would have done:
try { /* init code here */ }
catch (Exception ex)
{
// Passing original exception as inner exception
Exception ocrex = new OCRException("Engine failed to initialize", ex);
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
// Passing initialization failure as inner exception
ocrex = new OCRException("Failed to deinitialize engine!", ocrex);
}
throw ocrex;
}
You have two possible exception conditions: one in which the first method failed, and one in which both methods failed.
You're already defining your own exception class. So create another (or extend the first) with a RelatedException or PriorException property. When you throw the exception in the second case, save a reference to the first exception in this property.
It's up to the exception handler that catches this exception to figure out what to do with the second exception.

Categories

Resources