so currently i am writing a program something like this:
try
{
mainprocessing();
}
catch (exception e)
{
//first catch block.
//do something here
}
mainprocessing()
{
try
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
}
catch (NullReferenceException e)
{
//second catch block
//something here to handle it
}
}
But when I run the program now, if string value is null, the exception will be handled in the first catch block. However I want it to be handled in the second catch block. Is there any way to manipulate this?
Didn't read the question the proper way, was thinking you want to get explicit into the top level exception.
When a value is null and trying to access this variable, there will be no reference to an actual object and so an NullReferenceException will be thrown but in this case you are allocating value to an reference so there is another exception thrown rather than NullReferenceException.
The only way to found out which Exception is been thrown, add another catch block below the NullReferenceException.
catch (NullReferenceException e)
{
//second catch block
//something here to handle it, LOG IT!
}
catch (Exception exception)
{
Type exceptionType = exception.GetType();
}
When an Exception has been handled(catched) by the program it returns to the point where this function has been invoked, in this case 'mainprocessing'.
If you explicit WANT to get into the most top level Exception handling block, just throw a new Exception inside the catch, like this:
mainprocessing()
{
try
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
}
catch (NullReferenceException e)
{
//second catch block
//something here to handle it, LOG IT!
throw new Exception("top level exception");
}
}
As mentioned in the comments handling exceptions is not the way to handle flow control in C#. You use them if something unexpected happens, something you are not able to check in advance, before starting your process (e.g. file is corrupted and your read is aborted unexpectedly).
In your case just go with simple if check:
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
if (string.IsNullOrWhiteSpace(value))
{
// Handle the null/empty string here.
// From what you said probably the logic you wanted to use in your second catch block.
}
EDIT:
To handle the exception on the level of ReadCell just check if it's null before accessing the value. Then you have a couple of options. You can abort the execution (return) or try to get an instance of ReadCell.
if (ReadCell == null)
{
// abort the execution, create
}
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
Alternatively just indent several ifs:
if (ReadCell != null)
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
if (string.IsNullOrWhiteSpace(value))
{
// Handle the null/empty string here.
// From what you said probably the logic you wanted to use in your second catch block.
}
}
else
{
// Handle null case for ReadCell.
}
Here's how you should handle exceptions in your specific scenario:
private void btnDataStuff_Click(object sender, EventArgs e)
{
try
{
ProcessSomeData();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
MessageBox.Show("Inner exception: " + ex.InnerException.Message);
}
}
private void ProcessSomeData()
{
try
{
// Code where NullReferenceException exception happens
}
catch (NullReferenceException ex)
{
throw new ApplicationException("Data is null!!!", ex);
}
}
This is the proper way to handle and propagate your exceptions. I think this is what you originally wanted to accomplish. If NullReferenceException exception happens in the ProcessSomeData method - it will be propagated as a new exception with Data is null!!! message but it will also keep the original exception because it stores critical information for later debugging (call stack among other things). This way, you can have "nice" error messages in your application for the end user and original exceptions for the programmer to debug if needed.
This is a very simple example though. Please read this to learn best practices when handling exceptions. It's one of the most important aspects of programming that you will (have to) learn - you will eventuall learn it either way but why take the hard path when you can make your life easier from the start.
Also read up on C# coding conventions so you can write quality code from the start.
Other posters hinted that you should validate your data for null instead of catching exceptions and in most cases this is true but in case you still do want to catch some specific exceptions you now know a proper way to do so.
Related
I'm a beginner programmer and I have been faced with exceptions recently. I've done this small test below and the output I received was not the same as the one I expected.
static void Main(string[] args)
{
ushort var = 65535;
try
{
checked { var++; }
}
catch (OverflowException)
{
Console.WriteLine("Hello!");
throw;
}
catch
{
Console.WriteLine("Here I am!");
}
}
I was expecting the program to do the following:
Try to var++, fail and create an OverflowException;
Enter Catch (OverflowException) and write "Hello!";
Throw an Exception and enter catch;
Write "Here I am!".
However, I only got on screen "Hello!".
EDIT: Thanks to those who commented. I think I'm starting to understand. However, my confusion originated because of this book I'm reading: C# 4.0.
I could show the text, however it is in Portuguese. I'm going to translate what it says: "Sometimes it is useful to propagate the exception through more than one catch. For example, let's suposse it is necessary to show a specific error message due to the fact that the "idade" is invalid, but we still need to close the program, being that part in the global catch. In that case, it is necessary to propagate the exception after the execution of the first catch block. To do that, you only need to do a simple throw with no arguments."
Example from the book
In this example of the book you can see the programmer do the same thing I did. At least it looks like it. Am I missing something? Or is the book wrong?
Hope you can help me. Thanks!
In short, you are doing it wrong. Let's visit the documentation
Exception Handling (C# Programming Guide)
Multiple catch blocks with different exception filters can be chained
together. The catch blocks are evaluated from top to bottom in your
code, but only one catch block is executed for each exception that
is thrown.
Although it doesn't specifically say you can't catch an exception that has been re-thrown in an exception filter, the fact is you can't. It would be a nightmare and have complicated and unexpected results.
That's all to say, you will need another layer (inner or outer) of try catch to catch the exception that is thrown in catch (OverflowException)
You'll get the output you expected if you nest try/catch blocks:
static void Main(string[] args)
{
try
{
ushort var = 65535;
try
{
checked { var++; }
}
catch (OverflowException)
{
Console.WriteLine("Hello!");
throw;
}
}
catch
{
Console.WriteLine("Here I am!");
}
}
I have two articles on exception handling I link often. I personally consider them required reading when dealing with them:
https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
As for this case, you are not throwing a exception. You are re-throwing one you caught. Think of it like a fisherman doing "catch and release". It can be used for some scenarios, like this time I wrote a TryParse replacement for someone stuck on .NET 1.1:
//Parse throws ArgumentNull, Format and Overflow Exceptions.
//And they only have Exception as base class in common, but identical handling code (output = 0 and return false).
bool TryParse(string input, out int output){
try{
output = int.Parse(input);
}
catch (Exception ex){
if(ex is ArgumentNullException ||
ex is FormatException ||
ex is OverflowException){
//these are the exceptions I am looking for. I will do my thing.
output = 0;
return false;
}
else{
//Not the exceptions I expect. Best to just let them go on their way.
throw;
}
}
//I am pretty sure the Exception replaces the return value in exception case.
//So this one will only be returned without any Exceptions, expected or unexpected
return true;
}
But as a rule of thumb, you should be using stuff like "finally" blocks for cleanup work rather then catch and release. throw inside a catch block is something you use rarely.
I have the following code:
try
{
retval = axNTLXRemote.IsUnitPresent(_servers[0].IPAddress, 1, _servers[0].RemotePort, _servers[0].CommFailDelay * 1000);
}
catch (COMException ce)
{
throw ce;
}
Which gives me the followig warning which I want to get rid of:
CA2200 : Microsoft.Usage : 'Connect()' rethrows a caught exception and specifies it explicitly as an argument. Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.
I have read the following The difference between try/catch/throw and try/catch(e)/throw e and I understand that the 'throw ce; will reset the stack trace and make it appear as if the exception was thrown from that function.
I want to simply change it to a 'throw' instead of a 'throw ce' which will get rid of the warning.
What is the difference in the following catches:
catch (COMException ce)
{
throw;
}
and
catch (COMException)
{
throw;
}
Do I only need to have 'COMException ce' if I wish to somehow use the ce variable?
Also, when I perform a 'throw' or 'throw ce', is it the calling function that will handle or catch it?? I'm a little unclear about this.
The only difference is that with catch (COMException ce), you are assigning the exception to a variable, thereby letting you access it within the catch block. Other than that, it is in every way identical.
I'm not sure what the question is here. If you want to access the exception object, you must give it a variable name in the catch clause.
No matter how or where an exception is thrown, the exception will bubble up through the call stack to the closest catch block that matches.
Here's an example.
void Method1()
{
try
{
Method2();
}
catch // this will catch *any* exception
{
}
}
void Method2()
{
try
{
Method3();
}
catch (COMException ex) // this will catch only COMExceptions and exceptions that derive from COMException
{
}
}
void Method3()
{
// if this code were here, it would be caught in Method2
throw new COMException();
// if this code were here, it would be caught in Method1
throw new ApplicationException();
}
I'm sure someone will jump in with an uber-technical answer, but in my experience the answer to your first two questions is that there is no difference, and as you stated you'd only include ce if you intended to use it to write the stack trace to a log or display the message to the user or similar.
The throw will send the exception up the chain. That may be the calling method or, if your method has several nested try/catch blocks, it will send the exception to the next try/catch block that the current try/catch block is nested within.
Here are a couple good resources to check out if you want to read further on the subject:
Exception Handling
Design Guidelines for Exceptions
There is no difference in both cases, but only when exception variable should be used for stack/message etc.
So:
catch(ComException);
and
catch(ComException ex);
statements will produce similar MSIL, except local variable for ComException object:
.locals init ([0] class [mscorlib]System.Exception ex)
I know, we can use try-catch block to handle exceptions. But I have some doubts in the usage of Try-Catch.
What is the difference between
try
{
//Some code
}
catch
{
}
and
try
{
//Some code
}
catch(Exception)
{
}
and
try
{
//Some code
}
catch(Exception oops)
{
}
In my program, I need to catch all exceptions and I don't want to log them. From the above mentioned Try-Catch blocks, which should be used?
Using a catch without a parameter is no longer useful as of framework 2.0, as all unmanaged exceptions are wrapped in a managed exception. Before that you could use it to catch exceptions thrown by unmanaged code.
You can specify just the type of the exception if you don't want to use any information from it, but usually you would want a name for it so that you can get to the information:
try {
// some code
} catch(Exception) {
// i don't care about any information in the Exception object, just the type
}
vs.
try {
// some code
} catch(Exception ex) {
// use some information from the exception:
MessageBox.Show("Internal error", ex.Message);
}
You should always try to have an exception type that is as specific as possible, as that makes it easier to handle the exception. Then you can add less specific types to handle other exceptions. Example:
try {
// some database code
} catch(SqlException ex) {
// something in the database call went wrong
} catch(Exception ex) {
// something else went wrong
}
So far you use catch (Exception), the first and the second are the same. You catch everything in this case. When you like to catch a specific exception like UnauthorizedAccessException, you have to use the second one like this:
try
{
//Some code
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(oops.Message);
}
In the third case you can use the Exception through the variable oops.
For example:
try
{
//Some code
}
catch (Exception oops)
{
MessageBox.Show(oops.Message);
}
Or with a specific exception:
try
{
//Some code
}
catch (UnauthorizedAccessException oops)
{
MessageBox.Show(oops.Message);
}
Generic try catch, this will catch any type of exception
try
{
//Some code
}
catch
{
}
This will catch the specific type of exception that you specify, you can specify multiple.
try
{
}
catch (UnauthorizedAccessException)
{
}
This will do the same as above but give you a variable that has access to the properties of an exception.
try
{
}
catch (UnauthorizedAccessException ex)
{
}
You should be using the last one, and handling in a clean way your exception.
The first too way are the same but are "Eating Exceptions", witch is the worst thing to do.
At least log your exception!
Your first and second example are the same. They will both catch any exception, without any information about the exception. The third exception stores the exception in oops, which you can then use to get more information about the exception.
Look at msdn documentation: http://msdn.microsoft.com/en-us/library/vstudio/0yd65esw.aspx
The best is specify which kind of errors you would like catch.
The third one is the best...
You can catch any kind of specific exception and it will be precise... This helps in identifying the exact exception and easy for us to correct them as well
For eg: one can catch DivisionByZeroException, TargetInvocationException, ArrayOutOfBoundException, etc...
They are all pretty much the same (I assume the first is shorthand for writing the 2nd), the difference with the last is you are putting the exception object into a variable so you can use it in the catch.
Usually when I see code like this I tend to worry as it's generally not a good idea as you could be masking bigger problems with your application.
Rule of thumb - handle what you can, let everything else bubble up.
i think it has the same function - To trace where the error is set/ or where did something get wrong,
using try-catch this way
> try {
//some codes
}
catch
{
//anything
//e.g.:
MessageBox.Show("Something is wrong!");
}
this tells the that there is something wrong but didn't show the detailed report. (Clever way to hide some errors is don't put anything in the catch{} xD, but this is not advised to do)
the next is to show detailed report of the error
try
{
//some codes
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
hope this helps! :D
//I have written code in Catch Block
try {
} catch(Excepetion ex) {
// I have written code here If Exception Occurs then how to handle it.
}
You can put a try catch inside the catch block, or you can simply throw the exception again. Its better to have finally block with your try catch so that even if an exception occurs in the catch block, finally block code gets executed.
try
{
}
catch(Excepetion ex)
{
try
{
}
catch
{
}
//or simply throw;
}
finally
{
// some other mandatory task
}
Finally block may not get executed in certain exceptions. You may see Constrained Execution Regions for more reliable mechanism.
The best way is to develop your own exceptions for different Layers of application and throw it with inner exception. It will be handled at the next layer of your application. If you think, that you can get a new Exception in the catch block, just re throw this exception without handling.
Let's imagine that you have two layers: Business Logic Layer (BLL) and Data Access Layer (DAL) and in a catch block of DAL you have an exception.
DAL:
try
{
}
catch(Excepetion ex)
{
// if you don't know how should you handle this exception
// you should throw your own exception and include ex like inner exception.
throw new MyDALException(ex);
}
BLL:
try
{
// trying to use DAL
}
catch(MyDALException ex)
{
// handling
}
catch(Exception ex)
{
throw new MyBLLException(ex);
}
try
{
// Some code here
}
catch (Exception ex)
{
try
{
// Some more code
}
catch (Exception ex)
{
}
}
For the lines of code that could throw an exception in catch block make extra explicit try..ctach block. Besides consider having finally block, to have lines to run by all means there. The same question may raise for the finally block. So if your code is likely to throw some exception in the finally block, you could also add try..catch there.
try
{
}
catch (Exception ex)
{
try
{
// code that is supposed to throw an exception
}
catch (Exception ex1)
{
}
// code that is not supposed to throw an exception
}
finally
{
try
{
// code that is supposed to throw an exception
}
catch (Exception ex1)
{
}
// code that is not supposed to throw an exception
}
Double-faulting often happens in well-designed 3g programming languages. Since protected mode and the 286, the general design for hardware languages is to reset the chip on a triple fault.
You are probably ok designing your way out of a double fault. Don't feel bad about having to do something to stop processing / report an error to the user in this case. If you run into a case where, eg., you catch an IO exception (reading/writing data) and then try to close the stream you're reading from, and that also fails, its not a bad pattern to fail dramatically and warn the user that something truly exceptional happened.
A catch block isn't special in any particular way. You will have to either use another try/catch block or not handle the error.
My friend Atul.. if you if write try..catch in catch block, and if again exception occurs in inner try..catch, same problem will raise again.
So address this issue you can handle those errors in application level events in Global.asax
check below links..
http://msdn.microsoft.com/en-us/library/24395wz3%28v=vs.100%29.aspx
http://msdn.microsoft.com/en-us/library/fwzzh56s%28v=vs.80%29.aspx
let me know if this works for you.. :)
How can I handle an expected exception?
I have code in my MVC controller that calls the following:
u.RowKey == new SimplerAES().Dec(HttpServerUtility.UrlTokenDecode(id)));
In my other SimplerAES class:
public string Dec(byte[] encrypted)
{
return encoder.GetString(Decrypt(encrypted));
}
public byte[] Decrypt(byte[] buffer)
{
try {
MemoryStream decryptStream = new MemoryStream();
using (CryptoStream cs = new CryptoStream(decryptStream, decryptor, CryptoStreamMode.Write))
{
cs.Write(buffer, 0, buffer.Length);
}
return decryptStream.ToArray();
} catch(CryptographicException e){
//... do something with it ...
return null; // I put the return null here as I got a syntax message saying
// not all code returns
}
}
Can someone please explain how I get the message that decrypt failed all the way up
to the point where I first try to get the RowKey. Do I have to put u.RowKey within
a try catch as well?
Just don't catch the exception in your method, unless you really need the "do something" part. If you don't catch the exception, it will bubble up the stack until there's code which does catch it.
If you do need to do something within that method, such as logging, you can catch the exception and rethrow it within your catch block using
throw;
Note that this is preferred over
throw e;
as the latter will rewrite the stack trace. It probably won't make much difference in this particular case, but it's worth being aware of.
I suggest you ignore cryptography for the moment, and go hunting for good articles or books on exception handling in C#. This MSDN page is probably a good starting point.
Assuming that you actually need to do something at this level, simply rethrow the exception:
catch (CrypotgraphicException e)
{
// Do something
throw;
}
However, it might be simpler not to catch it at all and let it bubble up higher to your other exception handler.
If you want to continue having the exception unwind the stack don't return null from the catch block. you need to throw (without the exception reference) to continue unwinding with the same exception.
e.g.
try
{
// Do stuff
}
catch(CryptographicException e)
{
// Do stuff to clean up
throw;
}
If you throw e (which has the existing exception object) you destroy some of the stack trace data which makes it less useful. If you want to add more information, wrap the existing exception in a new exception (as the InnerException) and then throw the new exception object. That way you preserve the full exception information.
try
{
// Do stuff
}
catch(CryptographicException e)
{
// Do stuff to clean up
Exception newEx = new Exception("Some further message", e);
throw newEx;
}
Note: Don't simply create the base Exception object, you should derive a new exception class from an existing base (if a suitable Exception class is not available) and use the derived version. This makes catching much easier because you can then catch the exact type you need and not have to have your catch block figure out what do do because you are throwing overly broad exceptions.
Only ever catch an exception if there is something useful you can do with it. Simply swallowing it an returning null in your Decrypt method is not useful. Instead, let the exception bubble up until it gets to a point where it can be usefully handled..
Do I have to put u.RowKey within a try
catch as well?
This would be a more appropriate place to catch the exception...