Exception catch, then rethrow question

  • Thread starter Thread starter Taylor
  • Start date Start date
T

Taylor

I've run in to code with this pattern:

try
{
// do some potentially bad stuff
}
catch(System.Exception ex)
{
throw ex;
}

I'm not clear as to what the coder had in mind when he caught the exception
only to turn around and rethrow it without doing anything else in the catch
block. Do you know why this would be done? Have you seen this pattern of
try-catch-rethrow before?


I can understand catching the exception, then trying to handle it, and then
throwing another exception if its determined that you can't handle it like
this:

try
{
// do some potentially bad stuff
}
catch(System.Exception ex)
{
if(success == false)
throw new MyNewException;
throw ex;
}

but thats not how it was written. It was simply the first pattern, and I'm
wondering if I'm missing something or does that produce the same effect as
simply not catching the exception in the first place?
 
Looks like testing code to me.
Maybe the person forgot to add the catch handling to it.
 
Hi Taylor,

The [try {something();} catch (ex) {throw ex;}] pattern is used with
great verve by newbies who have no idea how redundant it is (and a few
not-so-newbies). It's what they mistaken believe is 'error handling'.

|| does that produce the same effect as simply not catching
|| the exception in the first place?

Yes, just as you already knew before that seed of doubt was placed.
The best that could be said for it is that it is a placeholder for when they
want to add some value to it, like a message or some recovery/tidy up.

|| and I'm wondering if I'm missing something

You've lost that naivety, and now the doubt. ;-)

Regards,
Fergus
 
Or
code was originally there, and got edited out and the exception block wasn't
removed. this happens often.
 
Keyword "placholder", I get it. That makes sense. Instead of

// watch out for the next line
something();

[try {something();} catch (ex) {throw ex;}] seems to "pack more of a punch"
in the sense that its not simply a comment which is often ignored, but
rather a try/catch/throw to more clearly indicate the code might do some
dangerous stuff. Simply commenting would have produced the same effect, but
adds something for the user.

I thought maybe there was something else going on like the exception was
elevated/demoted/altered to some type other than System.Exception.

Thanks for the reassurance all.
 
Taylor said:
I've run in to code with this pattern:

try
{
// do some potentially bad stuff
}
catch(System.Exception ex)
{
throw ex;
}

I'm not clear as to what the coder had in mind when he caught the exception
only to turn around and rethrow it without doing anything else in the catch
block. Do you know why this would be done?


He would be passing the exception to a general exception handling routine.

Have a look at codeprojects website for more details. There is a post
referring to this further down in this newsgroup. Explaining what Microsoft
recommend about catching unhandled exceptions.

If you follow Microsoft's recommendation, there is no need for this try
block. Any unhandled exception will be caught in a delegate.

Have a look it's really good.
 
Hi Martin,

codeprojects.com is a terrific site, I reference it often. Most sites have
pretty crappy search engines, so I resort to google. Google didn't turn
this great article up though.

I have to take a close look.
Thanks much for the reference,
Taylor
 
but thats not how it was written. It was simply the first pattern, and I'm
wondering if I'm missing something or does that produce the same effect as
simply not catching the exception in the first place?

There's a slight difference - namely that the exception will no longer
have the full stack trace any more. For instance, compile this program
with debug enabled:

using System;

public class Test
{
static void Main()
{
try
{
GenerateException();
}
catch (Exception e)
{
Console.WriteLine (e);
}
}

static void GenerateException()
{
try
{
ReallyGenerateException();
}
catch (Exception e)
{
throw e;
}
}

static void ReallyGenerateException()
{
string x = "h";
char y = x[6];
}
}

Now either remove the try/catch block, or change "throw e;" to just
"throw;". The output will change from:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

to:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at System.String.get_Chars(Int32 index)
at Test.ReallyGenerateException() in c:\test\Test.cs:line 32
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

For this reason, I always prefer "throw" to "throw e".

(The difference in IL is between "throw" and "rethrow".)
 
Interesting! I'll use your advice. That subtle difference seems like it
could come in handy. Very useful.

Thanks Jon


Jon Skeet said:
but thats not how it was written. It was simply the first pattern, and I'm
wondering if I'm missing something or does that produce the same effect as
simply not catching the exception in the first place?

There's a slight difference - namely that the exception will no longer
have the full stack trace any more. For instance, compile this program
with debug enabled:

using System;

public class Test
{
static void Main()
{
try
{
GenerateException();
}
catch (Exception e)
{
Console.WriteLine (e);
}
}

static void GenerateException()
{
try
{
ReallyGenerateException();
}
catch (Exception e)
{
throw e;
}
}

static void ReallyGenerateException()
{
string x = "h";
char y = x[6];
}
}

Now either remove the try/catch block, or change "throw e;" to just
"throw;". The output will change from:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

to:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at System.String.get_Chars(Int32 index)
at Test.ReallyGenerateException() in c:\test\Test.cs:line 32
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

For this reason, I always prefer "throw" to "throw e".

(The difference in IL is between "throw" and "rethrow".)
 
Hi Jon

Or you could do

try
{
ReallyGenerateException();
}
catch (Exception e)
{
throw new Exception(e);
}

this returns two stack traces, a inner and a outer.

Gary

Jon Skeet said:
but thats not how it was written. It was simply the first pattern, and I'm
wondering if I'm missing something or does that produce the same effect as
simply not catching the exception in the first place?

There's a slight difference - namely that the exception will no longer
have the full stack trace any more. For instance, compile this program
with debug enabled:

using System;

public class Test
{
static void Main()
{
try
{
GenerateException();
}
catch (Exception e)
{
Console.WriteLine (e);
}
}

static void GenerateException()
{
try
{
ReallyGenerateException();
}
catch (Exception e)
{
throw e;
}
}

static void ReallyGenerateException()
{
string x = "h";
char y = x[6];
}
}

Now either remove the try/catch block, or change "throw e;" to just
"throw;". The output will change from:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

to:

System.IndexOutOfRangeException: Index was outside the bounds of the
array.
at System.String.get_Chars(Int32 index)
at Test.ReallyGenerateException() in c:\test\Test.cs:line 32
at Test.GenerateException() in c:\test\Test.cs:line 25
at Test.Main() in c:\test\Test.cs:line 9

For this reason, I always prefer "throw" to "throw e".

(The difference in IL is between "throw" and "rethrow".)
 
Gary van der Merwe said:
Or you could do

try
{
ReallyGenerateException();
}
catch (Exception e)
{
throw new Exception(e);
}

this returns two stack traces, a inner and a outer.

True - and that's what I'd use if I wanted to end up throwing a
different type of exception.
 
Back
Top