Exception.Data and Exception Handling Questions - c#

I have a couple questions about exceptions.
1) when you hit a catch block, swallowing means what exactly? I thought it was always rethrow or the existing exceptions is passed up to the next catch block.
2) If you add Exception.Data values to an excepction, I notice I have to do another throw; to grab that data futher up in another catch block later. Why?

Swallowing an exception means catching it and not doing anything useful with it. A common thing you might see is this:
try
{
DoSomeOperationThatMightThrow();
}
catch (Exception ex) // don't do this!
{
// exception swallowed
}
You usually don't want to catch a base Exception at all, it's better to catch and handle specific Exception types, and ideally you should only catch exception types that you can do something useful with at the level of code you're in. This can be tricky in complex applications, because you might be handling different errors at different levels in the code. The highest level of code might just catch serious/fatal exceptions, and lower levels might catch exceptions that can be dealt with with some error handling logic.
If you do catch an exception and need to rethrow it, do this:
try
{
DoSomething();
}
catch (SomeException ex)
{
HandleError(...);
// rethrow the exception you caught
throw;
// Or wrap the exception in another type that can be handled higher up.
// Set ex as the InnerException on the new one you're throwing, so it
// can be viewed at a higher level.
//throw new HigherLevelException(ex);
// Don't do this, it will reset the StackTrace on ex,
// which makes it harder to track down the root issue
//throw ex;
}

Swallowing an exception normally means having a handling block for the exception, but not doing anything in the block. For example:
try { 3/0; } catch DivideByZeroException { //ignore } //Note: I know this really wont' compile because the compiler is smart enough to not let you divide by a const of 0.
You have to rethrow because the first handler for an exception is the only one that will execute.
If you want the exception to bubble up you either don't handle it or you rethrow it. By the way, it's important to note that in .NET by just saying "throw" you'll preserve the stack trace. If you "throw Exception" you'll lose your stack trace.

Ok, you can handle the exception up to call stack you can do some thing like this:
public class A
{
public void methodA()
{
try
{
}
catch(Exception e)
{
throw new Exception("Some description", e);
}
}
}
public class B
{
public void methodB()
{
try
{
A a = new A();
a.methodA();
}
catch(Exception e)
{
//...here you get exceptions
}
}
}

Related

How to be explicit about NOT throwing an exception?

This might be a broad question, but recently I ahve wondered about the following: In our C# backend we have many places that wrap some code in a try/catch block, specifically calls to external WcF services. Some of these calls are crucial for the application so in the catch block we log the error and rethrow, like:
catch(Exception ex)
{
_logger.Error("Some good error message");
throw ex;
}
On the other hand there are services we allow to fail, but we still want to log the error, so they look like:
catch(Exception ex)
{
_logger.Error("Some good error message");
}
Now reading the code of team members I can not be sure if they forgot to throw or if this is the intended behaviour.
Q: Is there a way, resp. what is the default way, to explicitly NOT rethrow (without including a comment in the code).
I have considered something like this:
catch(Exception ex)
{
_logger.Error("Some good error message");
NotThrowingHereOnPurpose();
}
// ...
// and further below a private method
// ...
private void NotThrowingHereOnPurpose(){}
One approach that may be useful here is to change the way of invoking the code that you explicitly allow to fail in such a way that it does not look like a try/catch block at all.
For example, you could write a helper method that does error reporting, and call it with actions expressed as lambdas:
void InvokeFailSafe(Action action, Action<Exception> onFailure = null) {
try {
action();
} catch (Exception e) {
if (onFailure != null) {
onFailure(e);
}
}
}
Now instead of try/catch you would write this:
InvokeFailSafe(
() => {
... The code that may fail
}
, exception => _logger.Error("Some good error message: {0}", exception)
);
or like this, if you don't want anything logged:
InvokeFailSafe(
() => {
... The code that may fail
}
);
If you code things this way, there would be no doubts about a missing throw statement.
It's an opposite solution to dasblinkenlight's answer. Instead of notifying others that the exception mustn't be rethrown it would say that it must be.
If you only want to log it then use the Error method as usual. Otherwise, you can write an extension method for your logger to log and throw exceptions.
The method would take the catched exception and rethrow it using the ExceptionDispatchInfo class. The ExceptionDispatchInfo is used to rethrow the exception with the original stack trace information and Watson information. It behaves like throw; (without the specified exception).
public static void ErrorAndThrow(this ILogger logger, string message, Exception exception)
{
var exceptionInfo = ExceptionDispatchInfo.Capture(exception);
logger.Error(message);
exceptionInfo.Throw();
}
And use it this way:
try
{
}
catch (Exception ex)
{
// ex would be rethrown here
_logger.ErrorAndThrow("Some good error message", ex);
}
Q: Is there a way, resp. what is the default way, to explicitly NOT
rethrow (without including a comment in the code).
Ideal way would be not to catch a generic exception. Now, to throw or not that entirely depends on your case. You need to understand that Exception handling is used when you know what to do in case an exception occurs. So, only specific exceptions should be handled. Catching exceptions without knowing what you are catching will change the behavior of your application.
Now reading the code of team members I can not be sure if they forgot
to throw or if this is the intended behaviour.
This is something the author of the code can explain to you. But here is a learning to take from this. Your code should be self explanatory. In specific cases where you are unable to express yourself with the code, add a meaningful comment.
You can check this link for better understanding.
I actually found another way that kind of includes what other have suggested here, but uses a built in feature: exception filters. I was free to modify the example given in here to illustrate this:
public void MethodThatFailsSometimes()
{
try {
PerformFailingOperation();
}
catch (Exception e) when (e.LogAndBeCaught())
{
}
}
and then one could have two extension methods on Exception, say LogAndBeCaught and LogAndEscape like so:
public static bool LogAndBeCaught(this Exception e)
{
_logger.Error(#"Following exception was thrown: {e}");
return true;
}
public static bool LogAndEscape(this Exception e)
{
_logger.Error(#"Following exception was thrown: {e}");
return false;
}

When does the catch arguments get checked in a try/catch block c#

I'm having an issue with a try/catch block, but I can't seem to find out exactly how try/catch works when it's running that I think might have my answer. I have the following try/catch block:
try
{
...
}
catch (MyException e)
{
Log.Error("oh no!");
throw;
}
Now when I run this code I'm getting a System.TypeLoadException: Could not load type SDK.MyException from assembly "SDKSampleLibrary, Version... etc error.
I'm wondering 2 things. First, when does the computer check to see if MyException is there. Is it when it gets to the try or when it gets to the catch? Second, the SDKSampleLibrary.dll is there. How do I tell why it's not seeing it?
If the class MyException gets thrown within the try area, it will get handled inside the catch, See my example below where i throw a new exception which would get handled by the catch statement. However any other kinds of exceptions would not be handled/
try
{
throw(new MyException()); // handled by the catch
throw(new ParseException()); //not handled.
int test = "test" //not handled
}
catch (MyException e)
{
Log.Error("oh no!");
throw;
}
can also catch general exceptions to catch ALL exceptions like:
try
{
throw(new MyException()); // handled by the catch
throw(new ParseException()); //handled.
int test = "test" //handled
}
catch (Exception e)
{
Log.Error("oh no!");
throw;
}
The compiler sees the class since it is blue and does not give compile errors. The problems is happening when you are running the code. I think the problem is in de code that throws the exception which cannot create it. You could try to use the normal Exception type in the catch block and then set a break point.
The problem is not with the try/catch block but rather the problem is the type of exception that you are trying to catch as specified by the exception that your code is throwing. This exception occurs when the runtime tries to load the MyException object. You should make sure that the MyException inherits either from the Exception base class or from any of its children.

Try Catch handled at top of process

if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)

Unhandled exception when calling throw

catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
throw new Exception("Nepravilno ime uporabnika ali geslo");
}
else
{
throw new Exception("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
}
but i always get Unhandled exception. Why?
At the risk of stating the obvious... Because you're not catching the Exception you throw in your catch block? Or, perhaps, something else is being thrown in the try block that isn't an OracleException.
What are you expecting to happen?
Just to be totally clear (to make sure that we're on the same page), an exception that's thrown but never caught will result in an unhandled exception (by definition). Throwing an exception from within a catch block is identical to throwing it from anywhere else; there still needs to be a try-catch somewhere to catch it. For example, this exception will be caught:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) { }
But this one results in a new exception being propogated:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Never caught
}
And this code catches both exceptions:
try {
try {
throw new Exception("Out of cheese error"); // Caught in inner catch
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Caught in outer catch
}
}
catch (Exception e) {
Console.WriteLine(e.Message); // "418: I'm a teapot"
}
Your code does not in anyway swallow an exception. All it does is catch one type of exception and throw another type of exception. If you have an unhandled exception before you write this code, you will still have one after you write it.
--UPDATE --
Referring to your comment to another answer, if you want to display a message and stop executing code then try:-
catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
MessageBox.Show("Nepravilno ime uporabnika ali geslo");
}
else
{
MessageBox.Show("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
// this exits the program - you can also take other appropriate action here
Environment.FailFast("Exiting because of blah blah blah");
}
I assume you call hierarchy look like this:
Main
|-YourMethod
try {}
catch (OracleException) {throw new Exception("blah blah")}
So you see, the OracleException which occured in YourMethod is being caught by catch block, but then you throw a new one which goes into Main, where nothing handles it. So you should add an exception handler on the previous level.
Also, do not hide the original OracleException, throw your exception this way throw new Exception("your message", e). This will preserve the call stack.
Because you're only handling the OracleException. Nothing is handling the Exception() you are throwing.
You're catching the OracleException which means you're prepared to handle it - what does handling it mean to you? Logging it and moving on? Setting some state and moving on? Surely, you don't want to pop up gui in a data access component right? If you're not prepared to handle it, let it bubble up and handle it at an outer layer.
You also shouldn't throw exceptions of type Exception. Create your own strongly typed exceptions so they can be handled, or, simply log and call throw; which rethrows the original.
If you throw a new type of exception ensure you're passing the original exception as the inner exception to ensure you're not hiding details.
I did a write up on some best practices with C# exceptions:
Trying to understand exceptions in C#
Hope that helps

Can I execute multiple Catch blocks?

This is a bit abstract, but is there any possible way to throw an exception and have it enter multiple catch blocks? For example, if it matches a specific exception followed by a non-specific exception.
catch(Arithmetic exception)
{
//do stuff
}
catch(Exception exception)
{
//do stuff
}
It is perfectly acceptable to have multiple catch blocks of differring types. However, the behavior is that the first candidate block handles the exception.
It will not enter BOTH catch blocks. The first catch block that matches the exception type will handle that specific exception, and no others, even if it's rethrown in the handler. Any subsequent ones will be skipped once an exception enters a catch block.
In order to have an exception caught in BOTH blocks, you would need to either nest blocks like so:
try
{
try
{
// Do something that throws ArithmeticException
}
catch(ArithmeticException arithException)
{
// This handles the thrown exception....
throw; // Rethrow so the outer handler sees it too
}
}
catch (Exception e)
{
// This gets hit as well, now, since the "inner" block rethrew the exception
}
Alternatively, you could filter in a generic exception handler based on the specific type of exception.
No. It isn't possible to execute the code in both catch blocks for a single exception.
I would probably refactor the code in the generic exception block into something that can be called from either.
try
{
// blah blah blah
{
catch(Arithmetic ae)
{
HandleArithmeticException( ae );
HandleGenericException( ae );
}
catch(Exception e)
{
HandleGenericException( e );
}
Like others said the exception will be caught by the most specific catch block.
This brings up a frustration of mine though with exception handling. I wish you could do something like
catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex)
{
}
Instead of having to do
catch (ArgumentNullExcpetion e)
{
}
catch (ArugmentOutOfRangeException outOfRange)
{
}
I understand the reasoning against this that you probably do different things for different exceptions but sometimes I want combine them.
You can't have more than one exception block handle the same exception. But what you can do is catch the general exception, then attempt to cast to the more specific, like this:
catch (Exception exception)
{
var aex = exception as ArithmeticException
if (aex != null)
{
// do stuff specific to this exception type
}
// then do general stuff
}
If you were using VB.NET you could abstract your error handler in the Arithmetic exception into a function or method call that always returns false.
Then you could write something like:
Catch ex as Arithmetic When HandleArithmetic()
Catch ex as Exception
End Try
Not that I would advocate such usage, though I have seen it recommended for logging purposes before. I don't believe there is a C# equivalent.
This is known as exception filtering and isn't supported in C# (I'm told it is possible in VB.NET).
One work around would be to catch the general exception and then check the exception type in the catch block and do any specific processing on that before carrying on with the rest of the block.

Categories

Resources