try-catch - but a catch which catches everything

G

Guest

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
 
N

Nicholas Paldino [.NET/C# MVP]

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:
public bool IsInteger(string val)
{
bool result;

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

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

Guest

Hi Nicholas,
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

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

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

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
 
N

Nicholas Paldino [.NET/C# MVP]

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

Guest

Hi,

The first portion is now entirely clear. Thanks.

However, could you please give ur opinion on the second section.
Copy-pasting for ur ref.:
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.

Thanks a lot!

Benny

Nicholas Paldino said:
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]
- (e-mail address removed)

Benny said:
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
 
B

Bruce Wood

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
crap 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)".
 
N

Nicholas Paldino [.NET/C# MVP]

Benny,

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]
- (e-mail address removed)

Benny said:
Hi,

The first portion is now entirely clear. Thanks.

However, could you please give ur opinion on the second section.
Copy-pasting for ur ref.:
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.

Thanks a lot!

Benny

Nicholas Paldino said:
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]
- (e-mail address removed)

Benny said:
Hi Nicholas,

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

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


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

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
 
B

Bruce Wood

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.

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

Guest

Hi 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 said:
Benny,

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]
- (e-mail address removed)

Benny said:
Hi,

The first portion is now entirely clear. Thanks.

However, could you please give ur opinion on the second section.
Copy-pasting for ur ref.:
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

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.

Thanks a lot!

Benny

Nicholas Paldino said:
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]
- (e-mail address removed)

Hi Nicholas,

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

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


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

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
 
S

Scott Roberts

You should "never" have a catch-all like this: neither "catch" by
itself nor "catch (Exception ex)".

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

Nicholas Paldino [.NET/C# MVP]

Bruce,

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

Bruce Wood

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

Guest

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

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
 
G

Guest

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
 

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