This comes from a book but won't debug with correct message in my Visual Studio 2010, it just gives me Unhandled exception at throw new ApplicationException("Smth. bad happened", e);
Is there an error in the book or is it my VS2010 exception settings maybe? The console output is supposed to show that given the file does not exist the inner and outer trace will be printed along with File Not Found. Does it have to do with Just-in-time debugging?
Current Output:Unhandled Exception.........................................................
Desired output:http://www.introprogramming.info/wp-content/uploads/2013/07/clip_image008.png
class program
{
static void Main()
{
try
{
string fileName = "WrongFileName.txt";
ReadFile(fileName);
}
catch (Exception e)
{
throw new ApplicationException("Smth. bad happened", e);
}
}
static void ReadFile(string fileName)
{
TextReader reader = new StreamReader(fileName);
string line = reader.ReadLine();
Console.WriteLine(line);
reader.Close();
}
}
If you want to wrap an exception in your own and have it bubble up, you should remove the inner try, since every try needs a matching catch. Since you're wrapping an exception of your own with the original exception, it doesn't serve any purpose if you are immediately catching it.
try
{
string fileName = "WrongFileName.txt";
ReadFile(fileName);
}
catch (Exception e)
{
throw new ApplicationException("Smth. bad happened", e);
}
EDIT:
This is expected behavior. You're explicitly throwing an exception, and no one is handling it. The book is likely trying to make the point that you can wrap exceptions to provide additional information, while still preserving the original exception. Check to ensure that the file you're trying to open is in the right place.
As an additional note, you should really wrap the file stream in a using block to ensure that the underlying handles/resources are closed.
static void ReadFile(string fileName)
{
using (TextReader reader = new StreamReader(fileName))
{
string line = reader.ReadLine();
Console.WriteLine(line);
reader.Close();
}
}
You have to make sure that you the file "WrongFileName.txt" is in your project's Bin/Debug folder (you include the file in the project and set it's build action to Content and Copy always, if you want it not to throw the exception.
I presume that the book was trying to show, that when the file name is correct, the program will go through normally, but otherwise will cause error.
The catch block gets run because the file doesn't exist in this case and therefore the action inside is executed. This concrete action is to throw the exception again but with more helpful information. You can also see, that this new exception's constructor accepts the original exception as the second parameter, which means it will be included in this exception's InnerException property.
Related
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.
How can I get my exception from my class to show as a windows error ?
This is my class :
public class Editcap
{
private string _newFileName;
public void convertFileToLibpcap(string filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
_newFileName = fileInfo.FullName.Replace(fileInfo.Extension, "_new") + ".pcap";
invokeProcess(WiresharkProcesses.Editcap, string.Format("{2}{0}{2} -F libpcap {2}{1}{2}", fileInfo.FullName, _newFileName, "\""));
deleteFile(filePath);
}
private void deleteFile(string filePath)
{
try
{
File.Delete(filePath);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
public string getNewFileName()
{
return _newFileName;
}
}
From my form:
The function creates new wireshark file with different extension and should delete the old file. If it fails to delete, I want to show the message error in pop up window
Editcap editpcap = new Editcap();
editpcap.convertFileToLibpcap(file.FullName);
You don't need to do anything, the exception will bubble up all on it's own; it's how they work.
Just add a Try/Catch around your calling code:
try
{
Editcap editpcap = new Editcap();
editpcap.convertFileToLibpcap(file.FullName);
}
catch(Exception e)
{
MessageBox.Show("There was an error deleting the file.");
}
Note that there is no need (and in fact some harm) to catching and then re-throwing a new exception in your deleteFile method. You're changing the type of the exception from the more specific and informative IOException to the less expressive Exception, and you're also taking out a lot of the stack trace information. It would be better to just remove that try/catch entirely from deleteFile. It also means you can change the calling code to catch IOException instead of the global Exception. By doing this you can potentially have different catch blocks for different exceptions, allowing you to treat them differently (perhaps crash with one type, log an error for a different one, show a message to the user for something else, etc.).
class Program
{
static void Main(string[] args)
{
var getfiles = new fileshare.Program();
string realname = "*test*";
string Location = "SVR01";
foreach (var file in getfiles.GetFileList(realname,Location))
{getfiles.copytolocal(file.FullName); }
}
private FileInfo[] GetFileList(string pattern,string Location)
{
try
{
switch (Location)
{
case "SVR01":
{
var di = new DirectoryInfo(#"\\SVR01\Dev");
return di.GetFiles(pattern);
}
case "SVR02":
{
var di = new DirectoryInfo(#"\\SVR02\Dev");
return di.GetFiles(pattern);
}
case "SVR03":
{
var di = new DirectoryInfo(#"\\SVR03\Prod");
return di.GetFiles(pattern);
}
default: throw new ArgumentOutOfRangeException();
}
}
catch(Exception ex)
{ Console.Write(ex.ToString());
return null;
}
}
private void copytolocal(string filename)
{
string nameonly = Path.GetFileName(filename);
File.Copy(filename,Path.Combine(#"c:\",nameonly),true);
}
}
Am handle the default switch statement but not sure am doing right,some one please correct me .
Thanks in Advance
You should throw an exception only in cases where you don't expect something to happen. If a directory other than SRV01/02/03 is not expected, throwing exception could be fine. If you expect it to happen and want to handle it gracefully, don't throw an exception.
But catching the exception you just threw and writing it to the console in the same function doesn't make sense. You kill all the purpose of throwing an exception there. If you want to write an error to the console, you can do that directly in the default statement.
If you want to handle the case when GetFiles throws an exception, handle it specifically. Catching an exception and writing it to console does not make sense. If you catch it, it means that you know what to do with it. If you don't, don't catch it.
Say your network is dead and GetFiles raises IOException. You catch it and return null and your code will raise NullReferenceException. Because of that, you lose the information about why that exception is raised.
What do you want to do if network connection is lost? You want to exit? Then you don't need to do anything, an unhandled exception already does that for you. You need to continue running? Are you sure? If app exits successfully will it mean "it has completed everything it's supposed to do" or "there could have been problems but you don't care"? If you're sure it's ok to "ignore" the error, then catch the exception, inform and continue, it's fine. Just make sure of your intent. Exceptions aren't bad or evil. They are there because they are helpful.
I see that you simply need to check if a location is in a list of allowed locations. I don't think a switch is a good candidate for something like this. It looks more like configuration, maybe something along the following lines would allow you to read such values from a configuration file for example. Also the logic in each switch statement is the same, so if we can minimise this repetition, it's a bonus
private List<string> _allowedLocations
public YourClassConstructor()
{
_allowedLocations = new List()
{#"\\SVR01\Dev", #"\\SVR02\Dev", #"\\SVR02\Dev"}
}
private FileInfo[] GetFileList(string pattern,string location)
{
if (location == null)
throw new ArgumentNullException("location");
if (!_allowedLocations.Contains(location))
throw new ArgumentOutOfRangeException("location");
var di = new DirectoryInfo(location);
return di.GetFiles(pattern);
}
The default in a switch statement is basically a catch all (or what youre doing in your catch statement). If something lands in your switch statement and hits the default, it may as well gone to your catch. My suggestion, return a null and write to the console whatever your exception is. If your exception works, keep it as is. Like #SLaks said, you can do whatever you want in your default clause, because it is the switches form of a catch statement.
If it's only for an internal environment where you have full control of the network paths, then you have the option to make an enum for location, which would give you the advantage of each possibility showing up in Intellisense. I additionally agree with what Kevin pointed out, in that you are throwing the exception only to catch it yourself within the same method (an antipattern). The enum is my only suggestion, otherwise your understanding and implementation of default is correct (i.e., to catch all unexpected/invalid cases).
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;
}
Using MODI (Microsoft Office Document Imaging) OCR, sometimes the image doesn't contain any text. Therefore doc.OCR throws an exception.
public static string recognize(string filepath, MODI.MiLANGUAGES language = MODI.MiLANGUAGES.miLANG_RUSSIAN, bool straightenimage = true)
{
if (!File.Exists(filepath)) return "error 1: File does not exist";
MODI.Document doc = new MODI.Document();
doc.Create(filepath);
try
{
doc.OCR(language, false, false);
}
catch
{
//
}
MODI.Image image = (MODI.Image)doc.Images[0];
string result="";
foreach (MODI.Word worditems in image.Layout.Words)
{
result += worditems.Text + ' ';
if (worditems.Text[worditems.Text.Length - 1] == '?') break;
}
doc.Close(false);
System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
System.Runtime.InteropServices.Marshal.ReleaseComObject(image);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(image);
image = null;
doc = null;
GC.Collect();
GC.WaitForPendingFinalizers();
return result;
}
This code terminates the application, not what I need :(
How do I just make it fade away like nothing happened?
You are 95% of the way there with the code you posted:
try
{
doc.OCR(language, false, false);
}
catch
{
// Here you would check the exception details
// and decide if this is an exception you need
// and want to handle or if it is an "acceptable"
// error - at which point you could popup a message
// box, write a log or doing something else
}
That said it would be prudent to catch the exception type that occurs when the document is empty and then have a different exception handler for any other errors that may occur
try
{
doc.OCR(language, false, false);
}
catch (DocumentEmptyException dex)
{
}
catch
{
}
DocumentEmptyException is, I assume, not the exception type thrown - if you look at the docs for the OCR method (or via debug) you will be able to work out which exception type to catch
EDIT (After seeing your edit)
Are you sure the exception is being thrown from the doc.OCR(...) method? In your edit you added additional code after the catch, could it be coming from there instead?
For example, the line after the catch:
MODI.Image image = (MODI.Image)doc.Images[0];
If your document is empty and therefore the exception is thrown and ignored (as the catch block has nothing in it), does this line continue to work?
You are doing nothing in the catch block, just swallowing the exception which is very bad. The code continues to execute and you try to use the doc variable but because the .OCR call has failed it is more than possible that another exception is thrown later. For example doc.Images[0] will probably crash if the OCR has failed. So either terminate the execution of the method by returning something or put the entire method in a try/catch block.