This question already has answers here:
Best practices for catching and re-throwing .NET exceptions
(11 answers)
Closed 9 years ago.
Is it better to do this:
try
{
...
}
catch (Exception ex)
{
...
throw;
}
Or this:
try
{
...
}
catch (Exception ex)
{
...
throw ex;
}
Do they do the same thing? Is one better than the other?
You should always use the following syntax to rethrow an exception. Else you'll stomp the stack trace:
throw;
If you print the trace resulting from throw ex, you'll see that it ends on that statement and not at the real source of the exception.
Basically, it should be deemed a criminal offense to use throw ex.
If there is a need to rethrow an exception that comes from somewhere else (AggregateException, TargetInvocationException) or perhaps another thread, you also shouldn't rethrow it directly. Rather there is the ExceptionDispatchInfo that preserves all the necessary information.
try
{
methodInfo.Invoke(...);
}
catch (System.Reflection.TargetInvocationException e)
{
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e.InnerException).Throw();
throw; // just to inform the compiler that the flow never leaves the block
}
My preferences is to use
try
{
}
catch (Exception ex)
{
...
throw new Exception ("Add more context here", ex)
}
This preserves the original error, but it allows you to add more context, such as an object ID, a connection string, and stuff like that. Often my exception reporting tool will have five chained exceptions to report, each reporting more detail.
If you throw an exception without a variable (the first example) the stack trace will include the original method that threw the exception.
In the second example, the stack trace will be changed to reflect the current method.
Example:
static string ReadAFile(string fileName) {
string result = string.Empty;
try {
result = File.ReadAllLines(fileName);
} catch(Exception ex) {
throw; // This will show ReadAllLines in the stack trace
throw ex; // This will show ReadAFile in the stack trace
}
The first preserves the original stack trace of the exception, the second replaces it with the current location.
Therefore the first is by far the better.
I'll agree that most of the time you either want to do a plain throw, to preserve as much information as possible about what went wrong, or you want to throw a new exception that may contain that as an inner-exception, or not, depending on how likely you are to want to know about the inner events that caused it.
There is an exception though. There are several cases where a method will call into another method and a condition that causes an exception in the inner call should be considered the same exception on the outer call.
One example is a specialised collection implemented by using another collection. Let's say it's a DistinctList<T> that wraps a List<T>, but refuses duplicate items.
If someone called ICollection<T>.CopyTo on your collection class, it might just be a straight call to CopyTo on the inner collection (if say, all the custom logic only applied to adding to the collection, or setting it up). Now, the conditions in which that call would throw are exactly the same conditions in which your collection should throw to match the documentation of ICollection<T>.CopyTo.
Now, you could just not catch the exception at all, and let it pass through. Here though, the user gets an exception from List<T> when they were calling something on a DistinctList<T>. It is not the end of the world, but you may want to hide those implementation details.
Or you could do your own checking:
public CopyTo(T[] array, int arrayIndex)
{
if(array == null)
throw new ArgumentNullException("array");
if(arrayIndex < 0)
throw new ArgumentOutOfRangeException("arrayIndex", "Array Index must be zero or greater.");
if(Count > array.Length + arrayIndex)
throw new ArgumentException("Not enough room in array to copy elements starting at index given.");
_innerList.CopyTo(array, arrayIndex);
}
That's not the worse code because it's boilerplate and we can probably just copy it from some other implementation of CopyTo where it wasn't a simple pass-through and we had to implement it ourselves. Still, it's needlessly repeating the exact same checks that are going to be done in _innerList.CopyTo(array, arrayIndex), so the only thing it has added to our code is 6 lines where there could be a bug.
We could check and wrap:
public CopyTo(T[] array, int arrayIndex)
{
try
{
_innerList.CopyTo(array, arrayIndex);
}
catch(ArgumentNullException ane)
{
throw new ArgumentNullException("array", ane);
}
catch(ArgumentOutOfRangeException aore)
{
throw new ArgumentOutOfRangeException("Array Index must be zero or greater.", aore);
}
catch(ArgumentException ae)
{
throw new ArgumentException("Not enough room in array to copy elements starting at index given.", ae);
}
}
In terms of new code added that could potentially be buggy, this is even worse. And we don't gain a thing from the inner exceptions. If we pass a null array to this method and receive an ArgumentNullException, we're not going to learn anything by examining the inner exception and learning that a call to _innerList.CopyTo was passed a null array and threw an ArgumentNullException.
Here, we can do everything we want with:
public CopyTo(T[] array, int arrayIndex)
{
try
{
_innerList.CopyTo(array, arrayIndex);
}
catch(ArgumentException ae)
{
throw ae;
}
}
Every one of the exceptions that we expect to have to throw if the user calls it with incorrect arguments, will correctly be thrown by that rethrow. If there's a bug in the logic used here, it's in one of two lines - either we were wrong in deciding this was a case where this approach works, or we were wrong in having ArgumentException as the exception type looked for. It's the only two bugs that the catch block can possibly have.
Now. I still agree that most of the time you either want a plain throw; or you want to construct your own exception to more directly match the problem from the perspective of the method in question. There are cases like the above where rethrowing like this makes more sense, and there are plenty of other cases. E.g., to take a very different example, if an ATOM file reader implemented with a FileStream and an XmlTextReader receives a file error or invalid XML, then it will perhaps want to throw exactly the same exception it received from those classes, but it should look to the caller that it is AtomFileReader that is throwing a FileNotFoundException or XmlException, so they might be candidates for similarly rethrowing.
We can also combine the two:
public CopyTo(T[] array, int arrayIndex)
{
try
{
_innerList.CopyTo(array, arrayIndex);
}
catch(ArgumentException ae)
{
throw ae;
}
catch(Exception ex)
{
//we weren't expecting this, there must be a bug in our code that put
//us into an invalid state, and subsequently let this exception happen.
LogException(ex);
throw;
}
}
You should always use "throw;" to rethrow the exceptions in .NET,
Refer to the blog post Throw vs. Throw ex.
Basically, MSIL (CIL) has two instructions - "throw" and "rethrow" and C#'s "throw ex;" gets compiled into MSIL's "throw" and C#'s "throw;" - into MSIL "rethrow"! Basically I can see the reason why "throw ex" overrides the stack trace.
The first is better. If you try to debug the second and look at the call stack you won't see where the original exception came from. There are tricks to keep the call-stack intact (try search, it's been answered before) if you really need to rethrow.
I found that if the exception is thrown in the same method that it is caught, the stack trace is not preserved, for what it's worth.
void testExceptionHandling()
{
try
{
throw new ArithmeticException("illegal expression");
}
catch (Exception ex)
{
throw;
}
finally
{
System.Diagnostics.Debug.WriteLine("finally called.");
}
}
It depends. In a debug build, I want to see the original stack trace with as little effort as possible. In that case, "throw;" fits the bill.
In a release build, however, (a) I want to log the error with the original stack trace included, and once that's done, (b) refashion the error handling to make more sense to the user. Here "Throw Exception" makes sense. It's true that rethrowing the error discards the original stack trace, but a non-developer gets nothing out of seeing stack trace information, so it's okay to rethrow the error.
void TrySuspectMethod()
{
try
{
SuspectMethod();
}
#if DEBUG
catch
{
//Don't log error, let developer see
//original stack trace easily
throw;
#else
catch (Exception ex)
{
//Log error for developers and then
//throw a error with a user-oriented message
throw new Exception(String.Format
("Dear user, sorry but: {0}", ex.Message));
#endif
}
}
The way the question is worded, pitting "Throw:" vs. "Throw ex;" makes it a bit of a red herring. The real choice is between "Throw;" and "Throw Exception," where "Throw ex;" is an unlikely special case of "Throw Exception."
Related
assume we have following peace of code in C#:
try{
....
try{
throw new Exception1("exception1");
}catch(Exception exception){
...
throw new Exception2("exception2");
}
}catch(Exception exception){
...
log(exception.message);
}
is it possible in log point(outer catch) to access exception1 object and log that one as well?
Here are two reasonable examples of what I think you are talking about. They illustrate what I was trying to describe in the comments as well as what #Jonesopolis describes.
First, my case. Say you are writing a utility that calls some lower-level service that may throw. You may want to describe the behavior of the utility in a way that the exceptions that may bubble up have more meaning to the caller. In this case, I've documented that my utility will throw an ApplicationException if there is a problem.
I do this from two places, the first one when I check some pre-conditions (that the path name is neither null or empty and that it is a valid file name (I'm assuming that there is an IsValidFileName function I can call)).
But the other place is that if I try to do the operation and it throws (I haven't checked that File.ReadAllLines actually ever throws an IOException, but I'm guessing it can). In this case, I don't want to burden my users with catching a possible IOException, instead, I translated it into an ApplicationException that I document. I wrap the IOException with a catch and throw of my ApplicationException, but I include the IOException as the inner exception so that debugging and tracking down other issues works. The code looks like:
public IEnumerable<string> AccessFile(string pathName)
{
if (string.IsNullOrEmpty(pathName) || !IsValidFileName(pathName))
{
throw new ApplicationException("Invalid Path Name");
}
try
{
var result = File.ReadAllLines(pathName);
return result;
}
catch (IOException ex)
{
throw new ApplicationException("Error Accessing File", ex);
}
}
It's that second parameter to the ApplicationException that sets up the inner exception. This pattern is very common.
The other example is what #Jonesopolis describes.
Here I have a work function doing something. My application architecture demands that I do logging at the level of whatever the DoSomethingImportant function is at. So, it catches any exceptions that get thrown at a lower level. However, that code wants to bubble up any exceptions to the DoSomethingImportant function's caller. Here, it just uses the throw keyword with no argument. That rethrows the current exception and lets it bubble through.
It's important to use throw; with no arguments, and not throw ex;. The former allows the existing exception to bubble up. The latter unwinds the stack at the catch site, and then throws a new exception, losing all the stack information that might point to the faulting location.
This is the typical code that I'm talking about. It's also a very common pattern:
public void DoSomethingImportant()
{
try
{
DoSomethingLowLevel();
}
catch (Exception ex)
{
GetLogger().Log(ex);
throw;
}
}
I have a code that looks like this (sorry for the Java bracket style):
class SomeClass {
public static void doSomethingRisky() {
try {
SomeRiskyFunction();
} catch (Exception e) {
throw e;
}
}
}
class MainClass {
public void callSomethingRisky() {
try {
SomeClass.doSomethingRisky();
} catch (Exception e) {
FinallyHandleTheException(e);
}
}
}
Basically, SomeClass will be a library and I want to design it so that all exceptions will be handled by the calling program (who may or may not choose to display a message about the exception).
My question is about the use of try/catch&throw in the doSomethingRisky() from SomeClass. Is it redundant or is it necessary? I mean, if I leave it off and the function does encounter an Exception during runtime, will it crash the program because nothing catches the Exception inside THAT function, or does it still pass it to the caller (callSomethingRisky()) where it is gracefully handled?
Same question for Java. Thanks!
The try/catch with throw e; in doSomethingRisky does exactly one thing: it destroys the stack-trace information. That probably isn't what you wanted, so the try/catch should be removed - it will already bubble-up as expected.
For info, if it was just throw; (rather than throw e;) then it would merely be redundant, rather than destructive.
It will pass to the caller in both ways.
One of the uses of the construct you show above is to log the exception in the procedure, but still throw it so somewhere up the call stack a catch can handle the exception.
One thing to keep in mind, use throw in this situation instead of throw e to avoid loosing stack trace information.
In your case it is redundant. Often developers will add more information to the exception, or create a new exception with the original exception embedded as an inner exception. But to simply catch and rethrow is redundant.
I have there piece of code
//Code 1 Code 2 Code 3
try try try
{ { {
//Exp occur //Exp occur //Exp occur
} } }
catch (Exception e) catch (Exception) catch
{ { {
//Handle exp //Handle exp //Handle exp
} } }
What is the difference between all of three codes
P.S. I'm new to C# and as far as Java or Objective-C is concerned this syntax throws error
Code 1
Its catching Exception in an object e which can be later used for exception handling. For example you can log the Message property or view stack trace using e.Message or e.StackTrace
Code 2
You are catching all the exception of the base type Exception but since you don't have any object related to it, you can only throw that exception so that it can bubble up or you may ignore the exception. If in that code you had :
catch(InvalidCastException)
Then all the InvalidCastException will be handled in the block without the exception object
Code 3
You are catching all type of exceptions irrespective of their type, which is similar to your code 2 with base class Exception
try-catch - MSDN
Although the catch clause can be used without arguments to catch any
type of exception, this usage is not recommended. In general, you
should only catch those exceptions that you know how to recover from.
Its always better if you catch specific exceptions before catching the base one. Something like.
try
{
}
catch(InvalidCastException ex)
{
}
catch(Exception ex)
{
}
try - catch - MSDN
It is possible to use more than one specific catch clause in the same
try-catch statement. In this case, the order of the catch clauses is
important because the catch clauses are examined in order. Catch the
more specific exceptions before the less specific ones. The compiler
produces an error if you order your catch blocks so that a later block
can never be reached.
Code 1 - fairly normal catch, hopefully doesn't need explanation
Code 2 - You want to execute a particular piece of code when a particular exception occurs, but you have no intention of actually interacting with the exception object. Should almost always have a throw; statement at the end, so that someone else higher up the stack who does care can catch it.
Code 3 - You want the code to execute for any exception(*) (except for any caught by earlier catch clauses of the same try). Again, should almost always include a throw; so that higher code can catch and actually process the exception.
At some level (possibly just at the top level, in the unhandled exception handlers for whatever environment you're in), something ought to be inspecting the exception object and probably logging it (if possible).
Here if you want to use the variable 'e' for getting the Exception message, Line or type.
//Code 1
try
{
//Exp occur
}
catch (Exception e)
{
//Handle exp
}
Below code for getting particular type of Exception and not dealing with Exception variable.
//Code 2
try
{
//Exp occur
}
catch (Exception)
{
//Handle exp
}
Below code catching all types of exceptions.
//Code 3
try
{
//Exp occur
}
catch
{
//Handle exp
}
if you plan to actually use the exception object, to log its properties to a log file or to show a message box or to throw another kind of exception and pass the current exception to its constructor, then you must use the first of the three (most left one).
in general the most used approach is the first one anyway, if you want to handle different kind of exceptions separately you can have multiple catch blocks starting with the most specialized on top and have the one you wrote at the bottom so that all exceptions not already handled will end in the generic catch block.
Nothing. They all catch EVERY exception that could possibly occur (by catching base type Exception or just any). This is typically frowned upon, for good reason. You should catch specific exceptions in the order you expect, and then if you do want to catch all exceptions catch Exception at the end.
try
{
}
catch (MyCustomException)
{
// do something for your custom exception
}
catch (Exception)
{
// do something for everything else
}
When you specify a variable for your exception such as catch (Exception e) you will have access to the stack trace (and other exception information) via e.Property or simply e.ToString() for the full message. It's also best practice to throw the exception when caught (well, unless you want to suppress it at this level and not allow your calling code to see the exception) so it bubbles up and you preserve the stack trace:
catch (Exception e)
{
// do something with e
throw;
}
Code 1 catches every exception (in your case!) and declares it, so you can use it later e.g. for Error-Messages.
MessageBox.Show(e.Message);
Code 2 also catches every exception (in your case!), but you can't use it, because it is not declared.
These two methods are not designed for that, they're designed to catch specific or custom exceptions.
try
{
//mycode
}catch(MyException myExc)
{
//TODO HERE
Console.Write(myExc.Message);
}
The third one catches all exceptions. Because there is no definition.
Take a look at: http://msdn.microsoft.com/de-de/library/0yd65esw%28v=vs.80%29.aspx
to learn more about exceptions in C#.
Differences:
Declaring Exception Parameter ex allows you to access the Exception object, in order to see and work with its properties, fields, methods and the like. This "ex" variable works like any parameter in any method.
Declaring Exception Type without parameter ex allows you to separate several "catch" areas for different types of exception. It is useless, and functionally equivalent to code sample 3 as you define it here, but if you need to do different actions depending on the type of the exception, and you do not need to access the exception object (you only need to know the type of the exception), then this is your way to go.
Untyped Catch Exception Handler allows you to add a fallback for any Exception that might be thrown, whatever its type. Since it is not parameterized, however, you won't have access to the Exception object's properties or methods. Both code sample 2 and code sample 3 therefore are equivalent.
Example:
try{ // code that throws exception }
catch(TypeException ex)
{
// code to handle exceptions of type TypeException
// I can access ex parameter, for example to show its Message property
MessageBox.Show(ex.Message);
}
catch(OtherTypeException)
{
// code to handle exceptions of type OtherTypeException
// I cannot access the ex parameter since it is not declared, but I know
// the exact type of the exception
MessageBox.Show("There was an exception of Other Type");
}
catch
{
// code to handle any other exception
// this is functionally equivalent to catch(Exception) since all typed exceptions
// inherit from the base type Exception
MessageBox.Show("An unknown exception has been thrown.");
}
...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
difference between throw and throw new Exception()
What would be the point of just having
catch (Exception)
{
throw;
}
What does this do?
By itself, the throw keyword simply re-raises the exception caught by the catch statement above. This is handy if you want to do some rudimentary exception handling (perhaps a compensating action like rolling back a transaction) and then rethrow the exception to the calling method.
This method has one significant advantage over catching the exception in a variable and throwing that instance: It preserves the original call stack. If you catch (Exception ex) and then throw ex, your call stack will only start at that throw statement and you lose the method/line of the original error.
Sometimes you might want to do something like this:
try
{
// do some stuff that could cause SomeCustomException to happen, as
// well as other exceptions
}
catch (SomeCustomException)
{
// this is here so we don't double wrap the exception, since
// we know the exception is already SomeCustomException
throw;
}
catch (Exception e)
{
// we got some other exception, but we want all exceptions
// thrown from this method to be SomeCustomException, so we wrap
// it
throw new SomeCustomException("An error occurred saving the widget", e);
}
It rethrows the exact same error, you gain nothing by this.
Sometimes you can use the catch method to do some logging or something without interupting your exception like this:
catch (Exception) {
myLogger.Log(LogLevels.Exception, "oh noes!")
throw;
}
I initially mistakingly thought this would unwind your stack, but this would only be if you would do the following:
catch (Exception err) {
throw err;
}
Only reason I can think of is if you want to put a breakpoint there during debugging.
It's also the default code being generated by some tools I think.
Simply rethrow the current exception, and that exception will keep its "source" and the stack trace.
What are your thoughts on code that looks like this:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
throw;
}
}
The problem I see is the actual error is not handled, just throwing the exception in a different place. I find it more difficult to debug because i don't get a line number where the actual problem is.
So my question is why would this be good?
---- EDIT ----
From the answers it looks like most people are saying it's pointless to do this with no custom or specific exceptions being caught. That's what i wanted comments on, when no specific exception is being caught. I can see the point of actually doing something with a caught exception, just not the way this code is.
Depending on what quality you are looking at it is not throwing the exception in a different place. "throw" without a target rethrows the exception which is very different from throwing an exception. Primarily a rethrow does not reset the stack trace.
In this particular sample, the catch is pointless because it doesn't do anything. The exception is happily rethrown and it's almost as if the try/catch didn't exist.
I think the construction should be used for handling the exceptions you know you will be throwing inside your code; if other exception is raised, then just rethrow.
Take into account that
throw;
is different than
throw ex;
throw ex will truncate the stack to the new point of throwing, losing valuable info about the exception.
public void doSomething()
{
try
{
// actual code goes here
}
catch (EspecificException ex)
{
HandleException(ex);
}
catch (Exception ex)
{
throw;
}
}
It wouldn't be, ideally the catch block would do some handling, and then rethrow, e.g.,
try
{
//do something
}
catch (Exception ex)
{
DoSomething(ex); //handle the exception
throw;
}
Of course the re-throw will be useful if you want to do some further handling in the upper tiers of the code.
Doing something like that is fairly meaningless, and in general I try not to go down the road of doing meaningless things ;)
For the most part, I believe in catching specific types of exceptions that you know how to handle, even if that only means creating your own exception with more information and using the caught exception as the InnerException.
Sometimes this is appropriate - when you're going to handle the exception higher up in the call stack. However, you'd need to do something in that catch block other than just re-throw for it to make sense, e.g. log the error:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
LogException (ex); // Log error...
throw;
}
}
I don't think just rethrowing the error would be useful. Unless you don't really care about the error in the first place.
I think it would be better to actually do something in the catch.
You can check the MSDN Exception Handling Guide.
I've seen instances where generic exceptions are caught like this and then re-packed in a custom Exception Object.
The difference between that and what you're saying is that those custom Exception objects hold MORE information about the actual exception that happened, not less.
Well for starters I'd simply do
catch
{
throw;
}
but basically if you were trapping multiple types of exceptions you may want to handle some locally and others back up the stack.
e.g.
catch(SQLException sex) //haha
{
DoStuff(sex);
}
catch
{
throw;
}
Depends on what you mean by "looks like this", and if there is nothing else in the catch block but a rethrow... if that's the case the try catch is pointless, except, as you say, to obfuscate where the exception occurred. But if you need to do something right there, where the error occurred, but wish to handle the exception furthur up the stack, this might be appropriate. But then, the catch would be for the specific exception you are handl;ing, not for any Exception
Generally having exception handling blocks that don't do anything isn't good at all, for the simple reason that it prevents the .Net Virtual Machine from inlining your methods when performance optimising your code.
For a full article on why see "Release IS NOT Debug: 64bit Optimizations and C# Method Inlining in Release Build Call Stacks" by Scott Hanselman