try-catch - but a catch which catches everything

try-catch - but a catch which catches everything

Post by QmVubn » Sat, 22 Oct 2005 01:42:07


Hi,

I have something like this:

try
{
// some code
}
catch // note - i am catching everything now
{
// do something
}

Will this sort of catch statement, catch 'unsafe' and 'kernal-level'
exceptions (even if the app is a simple asp.net app with no unsafe stuff)?
(just wanted to confirm as I had a debate with one of my friends - AFAIK i
feel it doesn't since no unsafe code is used and since Win32 exceptions are
mapped into managed .NET exception classes)


Also, in many cases, i have catch blocks which does nothing - because i
don't want any exception to be propagated...something like follows.

public bool IsInteger(string val)
{
bool result;

try
{
int.Parse(val);
result = true;
}
catch
{
result = false;
}
return result;
}

Is this OK (a good practice)?

Thanks,
Benny
 
 
 

try-catch - but a catch which catches everything

Post by Nicholas P » Sat, 22 Oct 2005 01:57:28

Benny,

If you use a catch, without specifying the exception, then that section
of code will be called whenever ANY managed exception is thrown in the try
block. Now, if there are SEH exceptions that are thrown that are not mapped
by the runtime, or somehow escape it, then the whole process is more than
likely going to come down, and it's a moot point anyways.

You also ask if the following is good practice:


This is horrible. In reality, you should use the static TryParse method
to see if it can be parsed, or perform some parsing on your own. Relying on
any exception to be thrown is a poor indicator of what the problem really
is. You should, for example, catch ArgumentException (if the argument is
null, then it can't be an integer), and FormatException (the string is not
an integer) and possibly OverflowException (it is an integer, but can not be
stored in an Int32, how you handle this is up to you).

If you get an OutOfMemoryException, then that has nothing to do with
your code, and you shouldn't just swallow it, as code up the stack might
need to know this is going on.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- XXXX@XXXXX.COM

 
 
 

try-catch - but a catch which catches everything

Post by QmVubn » Sat, 22 Oct 2005 02:17:04

Hi Nicholas,


What is SEH?
Also, my question actually is - whether to add catch(Exception ex) to make
sure that it catches *only managed* exceptions. In other words, if I omit
(Exception ex), will the catch block catch unsafe and kernel level exceptions
too (even if there isn't any unsafe code directly)?



Only the Double structure has a TryParse method - an int doesn't (I am using
.NET 1.1) - were you referring to some other method?

My objective is to make sure that the utility method is fail-safe. In other
words, whatever error happens, the method must return a false. If everythings
fine, it must return a true. This is to ensure that the calling method need
not worry about exceptions - these are just utility classes.

Please share your thoughts.

Thanks,
Benny
 
 
 

try-catch - but a catch which catches everything

Post by Nicholas P » Sat, 22 Oct 2005 02:34:31

Benny,

SEH is short for Structured Exception Handling, which is a way of
throwing/handling exceptions in unmanaged code. If the CLR picks up on
this, it is going to throw a managed exception with the details of the SEH.

"catch" will only catch managed exceptions. There is nothing else that
it can catch. If the CLR picks up on an unmanaged exception (that it knows
to look for), then it will wrap that in a managed exception and throw that.
If it escapes the CLR's watch, then the process is most likely coming down.

The only slight difference between catch and catch(Exception e) is that
with "catch" alone, you can catch anything, not just exceptions. You can
actually throw anything derived from object (i.e. anything) in managed C++,
but you can not do it in C#. With catch(Exception e), you will only catch
anything deriving from Exception (that isn't handled in previous catch
blocks).

The thing with catch (on it's own) is that you can't access anything on
the object that is thrown.

--
- Nicholas Paldino [.NET/C# MVP]
- XXXX@XXXXX.COM
 
 
 

try-catch - but a catch which catches everything

Post by QmVubn » Sat, 22 Oct 2005 02:42:07

i,

The first portion is now entirely clear. Thanks.

However, could you please give ur opinion on the second section.
Copy-pasting for ur ref.:

Thanks a lot!

Benny

"Nicholas Paldino [.NET/C# MVP]" wrote:

 
 
 

try-catch - but a catch which catches everything

Post by Bruce Woo » Sat, 22 Oct 2005 02:55:05

As Nicholas pointed out, this is bad practice:

public bool IsInteger(string val)
{
bool result;

try
{
int.Parse(val);
result = true;
}
catch
{
result = false;
}
return result;
}

You should "never" have a catch-all like this: neither "catch" by
itself nor "catch (Exception ex)". You should, instead, catch specific
exceptions that indicate the problem you are looking for. As Nicholas
pointed out, in your case these would be ArgumentNullException,
FormatException, and OverflowException.

* There is one case in which you have little choice but to "catch
(Exception ex)", and that is when calling methods written by third
parties, where the method documentation is incomplete and does not tell
you what exceptions the method can throw. For a good (?) example of
*** documentation, see the doc for the Crystal classes supplied with
.NET 1.1: the method parameter doc is barely adequate, and there is
_no_ mention of exceptions at all. In a situation like that, you can't
catch specific exceptions you don't know about, and you have to hold
your nose and "catch (Exception ex)".
 
 
 

try-catch - but a catch which catches everything

Post by Nicholas P » Sat, 22 Oct 2005 02:55:43

enny,

That is why I think you need to be EXTRA careful if they are utility
classes. You should not suck up exceptions that you have no intention of
sucking up, since they will just complicate your app later on.

If you are not using .NET 2.0, then you can use the Parse method on
Int32, and catch ^just^ the exceptions that I pointed out to you, since
those pertain to parsing the string, and nothing else. Then, in those
exception handlers, you can return false.


--
- Nicholas Paldino [.NET/C# MVP]
- XXXX@XXXXX.COM

"Benny" < XXXX@XXXXX.COM > wrote in message
news: XXXX@XXXXX.COM ...


 
 
 

try-catch - but a catch which catches everything

Post by Bruce Woo » Sat, 22 Oct 2005 03:08:15

> My objective is to make sure that the utility method is fail-safe. In other

Yes, but don't take "fail-safe" to extremes. If you catch an
OutOfMemoryException, is your method really being "fail-safe", or are
you just swallowing an important exception and doing nothing with it? I
would say the latter. You haven't helped your caller out any by
throwing away a system-level exception like OutOfMemoryException.

The general rule is simple: catch only exceptions with which you can
deal intelligently. There are only three situations in which I catch
exceptions:

1. When I want to transform the exception into a return value. For
example, in your case you want ArgumentNullException, FormatException,
and OverflowException to be transformed into a return of false,
indicating "this is not an integer." That's fair: each of those
exceptions is meaningful to you and your callers, it's just that you
want to change the way the caller receives that information: as a
return value rather than exception. OutOfMemoryException, on the other
hand, does _not_ mean "this is not an integer." It means that something
went horribly wrong deep inside the .NET Framework, so it's not
appropriate to transform it into a return value.

2. When I want to transform the exception into a different exception,
because the low-level exception isn't meaningful from the point of view
of the caller. For example, I might want to transform a
DivideByZeroException into an InvalidArgumentException, because it's
more appropriate to tell my caller that they passed an invalid
argument; my caller doesn't care that I later used that argument in a
division operation. (Yes, I know, bad programming practice: better to
check for zero up front. :-)

3. When I know that I can recover from the specific situation that a
specific exception indicates. For example, I might get an exception
attempting to parse an XML file against a schema, but my application
can recover from that situation by running the XML through a transform
to bring it up to the latest version. In this case, I catch the
exception and then take a different path through my app. This includes
the case in which my application might want to ignore a particular
exception and keep going anyway.

The bottom line in all three cases is that I catch a specific exception
when I know that I can do something meaningful with that exception.
Never catch an exception if you then don't know what to do with it.

In the case of an OutOfMemoryException, what is your method going to do
with it? Toss it away and keep going anyway? Is that a decision for
your method to make, or is that a higher-level decision for the calling
application? I would say the latter.
 
 
 

try-catch - but a catch which catches everything

Post by QmVubn » Sat, 22 Oct 2005 03:11:09

i Nicholas,

Thanks a lot!

I am now trying to unlearn this habit of mine and trying to think in ur
lines.

Thanks again!

Benny

"Nicholas Paldino [.NET/C# MVP]" wrote:

 
 
 

try-catch - but a catch which catches everything

Post by Scott Robe » Sat, 22 Oct 2005 03:38:04


Never say "never".

try
{
ModifyDB();
Commit();
}
catch
{
Rollbac();
throw;
}

Perhaps you don't consider this "catching" the exception since it is always
re-thrown?

Also, when processing a large list of items (e.g. reading millions of
records from a file) there are a myriad of things that can go wrong. Your
catch list would stretch for miles. However, you certainly don't want the
whole process to stop 90% of the way through because one record had an
error, do you? Log the exception, go on to the next item, deal with the
exception when the process has finished.
 
 
 

try-catch - but a catch which catches everything

Post by Nicholas P » Sat, 22 Oct 2005 03:53:53

Bruce,

It should be pointed out in #2 that the InnerException should be set on
such transforms.
 
 
 

try-catch - but a catch which catches everything

Post by Bruce Woo » Sat, 22 Oct 2005 05:41:05

Ah, yes. Point taken. I hadn't considered the rollback case.

Squirreling away the exception and dealing with it later is another
valid reason to "catch all" exceptions. Point taken, again. :-)
 
 
 

try-catch - but a catch which catches everything

Post by SmF2YW1hbj » Sat, 22 Oct 2005 12:38:02

Hi Benny,


As others have pointed out, this is universally regarded as bad practice,
except in a small number of very specific situations. It is one of those
things, like "goto's" that you can just take on authority.

Still, I'll give you an real-world example of why...

Some months ago, in a test utility, I had to introduce an exception handler.
Because it was just test code, I decided to do a "quick and dirty", as in
your example..

try
{
// some code
}
catch
{
// do something
}

Last week, I shifted to Visual Studio 2005, and my test utility stopped
working. I *eventually* found the reason. My code had, all along, an
underlying thread flaw. .Net CLR 2.0 detects this flaw, and raises an
exception. The exception happened to be caught in the catch-all, and the
symptoms of the problem arose later. If i didn't have the catch all, then the
exception would have gone straight to top, and halted the program
immediately, with a meaningful diagnostic.

My "quick and dirty" in the test utility ended up costing me some time. If
it had been complex production code, which I had inherited from someone else,
it could have been more serious, and could have cost a *lot* more time.

Regards,

Javaman
 
 
 

try-catch - but a catch which catches everything

Post by UGhpbGxpcC » Mon, 24 Oct 2005 23:15:03

Hi Benny,

You can implement the IsInteger routine without try/catch in .Net 1.1 using
the double.TryParse static method that has already been mentioned. It has a
parameter NumberStyles which you call with Integer, and is equivalent in
result to your previous method.

public static bool IsInteger(string s)
{
double result;
return double.TryParse(s, System.Globalization.NumberStyles.Integer, null,
out result);
}

Its a bit cryptic though that you have to use a method of double.

Hope this helps.

Regards,
Phil