Given the following code in C#:
public void CatchExceptionThenThrow()
{
try
{
StartThings();
}
catch (Exception)
{
throw;
}
}
I have converted that to VB as such using the dotnetfiddle VB.net converter:
Public Sub CatchExceptionThenThrow()
Try
StartThings()
Catch As Exception
Throw
End Try
End Sub
This throws a compile error on:
Catch As Exception
End of Statement expected
I then change that to:
Public Sub CatchExceptionThenThrow()
Try
StartThings()
Catch ex As Exception
Throw
End Try
End Sub
But this creates a warning "variable declared but never used". How do I go about throwing rather than throw exing in VB without getting the warning, all the while preserving the entirety of the stack trace as in the first C# example?
All good comments, and thanks for the redundancy information I realize the try/catch is completely not needed as this would have occurred with or without the try/catch. The question was more for curiosities sake in a scenario that, I suppose, has no real basis in (a good code) reality.
I had seen something similar in a blog post about exception handling recently and why to throw vs throw ex, and was just curious as to how to accomplish the same code in VB - as I'm not strong with VB and am trying to better understand it, and exception handling.
I had hoped I'd be able to find the blog post I referenced above, but was unable. The gist of it (which spawned the question) can be found: https://dotnetfiddle.net/741wAi
Just have an empty Catch like:
Try
StartThings()
Catch
Throw
End Try
But if you are not doing anything in the Catch block other than re-throwing it, then there is no point to have try-catch in first place.
You can have StartThings() without try-catch and in case of exception, the exception will propagate to the caller.
The reason you are getting warning for Catch ex As Exception, is that you caught the exception in variable ex but you are not using it anywhere.
If you're just catching Exception then your code is redundant, as has been pointed out. If however you're simplifying your example code and you are trying to catch only a specific type of exception and do other processing for other thrown Exceptions, then I hate to break it to you but it appears VB can't really do this so you'll have to put up with the warning. Obviously don't throw ex.
Related
Is there a difference when catching exceptions not of a type between :
try
{
...
}
catch (TaskCanceledException)
{
throw;
}
catch (Exception exception)
{
...
}
and :
try
{
...
}
catch (Exception exception) when (!(exception is TaskCanceledException))
{
...
}
Yes, there is.
In the second block of code you are filtering on general exception type. It is not meant to be filtered, what happens if "TaskCanceledException" is thrown? you are not handling it and it will escalate to enclosing code. You are not really meant to filter anything on "Exception" type since it is the parent for all other type of exception and it is the last point of handling exception. A better option would be to create a custom exception and put them in separate block of catch and filter on them if needed.
The first option is more correct compared to the second one. Though you should not be throwing any exception and stay away from them, unless it is a complete deal breaker. On top of that what is the point of putting a catch block with Exception type bellow TaskCanceledException catch block which throws exception? You are basically telling that "I Would like to handle all exception" when using catch with Exception type, but at the same time you through one exception in exceptional case. Either throw the original exception or handle them.
Hope this makes sense.
Refer to this link Stackoverflow
Catch blocks already allow you to filter on the type of the exception:
catch (SomeSpecificExceptionType e) {...}
The when clause allows you to extend this filter to generic expressions.
Thus, you use the when clause for cases where the type of the exception is not distinct enough to determine whether the exception should be handled here or not.
The Dixin's Blog explained the difference with code example and VS screenshots.
Exception filter does not unwind the stack, and catch block does unwind. When executing catch block, this catch block’s method becomes the top frame of the stack. As a result, all the methods called by current method are removed from the stack. In contrast, exception filter can be helpful for runtime debugging. For example, if above Catch method is executed:
My code looks like this
var i = 0;
try
{
i = faultyProcedure();
}
catch (Exception ex)
{
try
{
throw new CustomException("faultyProcedure called", ex);
}
catch (CustomException) {}
}
Though it works, it looks silly.
The custom exception does all the logging, mailing, etc. even exits the application if necessary.
Is there a way for the custom exception to catch/kill itself, so there is no need for the inner try/catch block?
So... you are using your CustomException to handle other exceptions? If that is the case, then I'm sorry to be the one to tell you, but it doesn't just look silly, it is silly.
That's not what exceptions are for.
Exceptions are designed to indicate exceptional situations, mainly things you don't have control over when you write the code, such as IO or network problems.
To handle exceptions you can write your code into any class, but there is no point of throwing a new exception just to handle an exception that was caught by a catch clause.
I believe this is an example of a vexing exception:
Vexing exceptions are the result of unfortunate design decisions. Vexing exceptions are thrown in a completely non-exceptional circumstance, and therefore must be caught and handled all the time.
The example in Eric Lippert's blog is int.Parse, but I think this code is just as valid as an example of a vexing exception.
I want the code calling a function to handle any exception raised in the function. If I write:
try
{
// Code than may raise an exception
}
catch
{
throw;
}
The exception will be passed back with the callstack. Could I write the following instead and get the same result? Is there any reason to use the try catch in this case?
// Code that may raise an exception
In the scenario you've presented, the only reason to catch, and then rethrow, the exception, is if you're doing something else in the catch block, like logging or cleanup. Otherwise, it's entirely a no-op.
Good on you that you're using throw, rather than throw e, by the way, if you do need this construct. The former preserves the callstack; the latter does not.
There is no reason to use try/catch in that case.
If you were logging any information or encapsulating the exception in a higher-level one, then the try/catch would be indicated.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
the difference between try/catch/throw and try/catch(e)/throw e
Pardon my stupidity, anyone knows difference between them?
try
{
return 1 / 0;
}
catch (Exception)
{
throw;
}
try
{
return 1 / 0;
}
catch
{
throw;
}
try
{
return 1 / 0;
}
catch (Exception e)
{
throw(e);
}
Will catch and rethrow only exceptions derived from Exception.
Will catch and rethrow any exception. (Edit: Since CLRv2, all exceptions are derived from Exception so this is identical to 1. See Eric Lippert's comment below).
Will catch any exception derived from Exception and throw it again, thus resetting the stack trace of the exception.
A catch clause without arguments can catch any type of exception. This is sometimes referred to as the "general" catch clause. You should probably never use this in a production application, but I suppose it might sometimes be useful for debugging. It looks like this:
catch
{
}
A catch clause can also specify the particular exception class that you want to catch. You should always do this in your applications because you're only supposed to catch exceptions that you know how to handle. For example, you might want to catch a DivideByZeroException; you'd do it like this:
catch (DivideByZeroException)
{
}
Of course, that has the side effect that you're unable to refer to the exception class itself inside of the catch block because you haven't assigned it to a variable. If you need to call properties or methods on the instance of the exception class that you catch, you'll need to include a named variable in the catch statement. That is probably what you're most used to seeing, and it looks like this:
catch (DivideByZeroException ex)
{
// do something with ex here
}
Then there are two ways to write the throw() statement, and it matters which one you choose:
The first just looks like this:
throw;
It is written without any arguments, and the purpose is to rethrow the caught exception while preserving the stack trace and as much information about the original exception as possible.
(There are still some edge cases where this can cause you to lose the stack trace, but generally this is much preferred over the alternative below.)
The second option passes an instance of an exception class as an argument, and looks like this:
throw(ex);
or this:
throw ex;
This also rethrows the specified exception, but as mentioned above, it has the downside of losing some of the stack trace information that tells you what method was responsible for throwing the exception. It's rare that you'll use this except to throw a new exception object that you create in the same method.
For example, if you wanted to catch a low-level exception and wrap it within a new exception object for consumption by a higher-level function, you would use this form.
The first two are equivalent.
The third one should generally be avoided: it rethrows the exception from its own stack frame, losing information about the original frames in the process.
catch (Exception) - Catches anything that derives from Exception class
catch (Exception e) - Catches anything that derives from Exception class and assign it to the variable e, which you can use.
catch - catches anything thrown.
There is no difference between example 1 and 2. Both rethrows the original exception, and both catches the general Exception. You would use example 1 if you wanted to catch a more specific exception, such as DivisionByZeroException.
For the last example, you are not re-throwing the exception; but throwing the same exception object that you caught. This causes the exception stacktrace to be re-set to the location where you throw it - which might be a problem because the stacktrace then does not point to the location in code, where the error actually occured.
The difference is that throw e; will throw an exception with a different stack trace. See this accepted answer.
I'm writing a custom class in C# and I'm throwing a couple exceptions if people give the wrong inputs in some of the methods. If the exception is thrown, will any of the code in the method after the throw still be executed? Do I have to put a break after the throw, or does a throw always quit the method?
When you throw an exception, the next code to get executed is any catch block that covers that throw within the method (if any) then, the finally block (if any). You can have a try, a try-catch, a try-catch-finally or a try-finally. Then, if the exception is not handled, re-thrown by a catch block or not caught at all, control is returned to the caller. For example, you will get "Yes1, Yes2, Yes3" from this code ...
try
{
Console.WriteLine("Yes1");
throw (new Exception());
Console.WriteLine("No1");
}
catch
{
Console.WriteLine("Yes2");
throw;
Console.WriteLine("No2");
}
finally
{
Console.WriteLine("Yes3");
}
Console.WriteLine("No3");
Throw will move up the stack, thus exiting the method.
I recommend stepping through your program with a debugger then you'll see for yourself what is going on. Very useful for learning!
I came here looking for an answer to the original post and almost missed a very valuable answer posted by Eric Lippert. Here's his answer posted in the comments:
Split this up into three questions.
(1) Will any of the code in the method after the throw be executed?
YES. If the exception was inside a try then code inside matching catch blocks or finally block will be executed. If there is no try block then NO. Control branches to the nearest enclosing finally, catch or (in vb) exception filter block up the stack.
(2) Do I have to put a break after the throw?
NO, never do that. The end point of the throw statement is not reachable; a throw is treated as a goto by the compiler. A statement immediately following a throw is not reachable and will never execute.
(3) Does a throw always quit the method?
NO. If the throw is in a try and the try has a matching catch block then the catch block can "eat" the exception. Only if there is no catch block does the exception do a non-local goto up the call stack.
If you have more questions about this, I recommend reading the C# specification; all this behavior is clearly documented.
Finally, it sounds like you are throwing "boneheaded" exceptions, as in "hey boneheaded caller, I told you to never give me that data". That's great because it prevents bugs in callers. But if you do that, you should make sure that the caller has some way of knowing what you expect! If the caller cannot figure out whether you're going to throw or not based on your documentation, then you haven't made a boneheaded exception, you've made a vexing exception. See http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx for details.
If you've wrapped your code in a Try...Catch...Finally block, then the code under Finally will always execute. For example:
Try
' do some stuff here
' Examine user input
If user input isn't valid
Throw new exception
Catch
Throw ' Just re-throws the same exception
Finally
' This code will execute, no matter what - exception or not
End Try
As an aside to your actual question: you might want to rethink using exceptions to provide validation info back to the user.
Raising exceptions is expensive resource-wise and slow. If you have a number of validation rules that you need to apply then write specific code for these - you should probably only rely on exception handling for things you don't anticipate.