Exception catch, then rethrow question

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?
 
R

Ron Vecchi

Looks like testing code to me.
Maybe the person forgot to add the catch handling to it.
 
F

Fergus Cooney

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
 
A

Alvin Bruney

Or
code was originally there, and got edited out and the exception block wasn't
removed. this happens often.
 
T

Taylor

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.
 
M

Martin Stainsby

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.
 
T

Taylor

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
 
J

Jon Skeet [C# MVP]

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".)
 
T

Taylor

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".)
 
G

Gary van der Merwe

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".)
 
J

Jon Skeet [C# MVP]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top