Exception catching - c#

What is the difference between
try
{
...
}
catch (NHibernate.ADOException exception)
{}
and
try
{
...
}
catch (exception ex)
{}

In the catch block you specify which exceptions you wish to catch. So if you have
try {}
catch(Exception e){}
it will catch all exceptions that derive from the Exception class (so ALL exceptions). If you have:
try{}
catch (NHibernate.ADOException exception){}
it will only catch exceptions that are or derive from ADOException. So if you get an ArgumentException, it will pass through as if there were no try/catch.

I'm assuming you meant
catch (Exception ex) {}
with the second snippet.
Then the difference is that the first one will only catch one specific type of exception, namely NHibernate.ADOException while the second one will enter the catch block for all exceptions that could possibly be thrown.
The second is usually bad practice since you're claiming to handle every conceivable type of error. However, it can make sense in the outermost scope as a catch-all for any exception that got through.

Using catch { Exception } is strongly not recommended, because this actually hides a bugs. In every place where exception may be thrown, it is necessary to catch only expected exception types, even if this requires to write more code lines. When unexpected exception is thrown, program must crash, this is the only way to fix the bug.

Related

Exceptions to Never Catch

I know that there are some exception types that cannot be caught in catch blocks, like StackOverflowException in .NET 2.0. I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
The way I would like to use this list of exception types is to check it every time I am using Exception in a catch block:
private static readonly Type[] _exceptionsToNotCatch = new Type[] { typeof(StackOverflowException) };
// This should never throw, but should not swallow exceptions that should never be handled.
public void TryPerformOperation()
{
try
{
this.SomeMethodThatMightThrow();
}
catch (Exception ex)
{
if (_exceptionsToNotCatch.Contains(ex.GetType()))
throw;
}
}
EDIT
I don't think I provided a very good example. That's one of the problems with trying to make an example trivial when trying to communicate one's meaning.
I never throw Exception myself, and I always catch specific exceptions, only catching Exception as follows:
try
{
this.SomeMethodThatMightThrow();
}
catch (SomeException ex)
{
// This is safe to ignore.
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
My question was meant as more of an academic one. What exceptions are only thrown by the system and should never be caught? I am worried about situations more like this:
try
{
this.SomeMethodThatMightThrow();
}
catch (OutOfMemoryException ex)
{
// I would be crazy to handle this!
// What other exceptions should never be handled?
}
catch (Exception ex)
{
// Could be some kind of system or framework exception, so don't handle.
throw;
}
This question was really inspired by the following:
System.Data.EntityUtil.IsCatchableExceptionType(Exception) in System.Data.Entity, Version=3.5.0.0
I would like to know which other exceptions are inadvisable to catch, or are associated with bad practices.
Here is the list of all exceptions you shouldn't catch:
Any exception you don't know what to do with
Here's the best practice for exception handling:
If you don't know what to do with an exception, don't catch it.
This may sound snarky, but they're both correct, and that's all you need to know.
It's generally not a good idea to do that.
You should catch the most specific exception(s) possible and only carry on execution of your program when it is safe to do so. E.g. if you're opening a file, it's perfectly reasonable to catch exceptions relating to file access / permission errors, but probably not much else. You certainly wouldn't want to catch an OutOfMemoryException and then blindly carry on. They're very different errors!
If you apply a blanket rule of what to catch, there's no guarantee that your program will be able to continue execution safely because you're not responding to specific situations, just applying a one size does not fit all solution.
Using Exception in the catch block would catch all exceptions that are catchable. I would say you should specify only exceptions that needs to be caught and let the ones you don't want to catch spill out. E.g.
try
{
}
catch(SqlException sqlex) //specific to database calls
{
//do something with ex
}
catch(FormatException fex) //specific to invalid conversion to date, int, etc
{
//do something with ex
}
catch(Exception ex)
{
//I didn't know this exception would be thrown
//log it for me or Rethrow it
}
Any other exception not in that list will not be caught
Okay so we've established it ain't a good idea. And we've established that programmers on SO prefer to opine from their high-horses rather than hand you a knife to stab yourself with, so for those with suicidal tendencies, let's start with these:
(Redacted my list and DRYing-up SO to point to Hans' list)
https://stackoverflow.com/a/5508733/17034

Reading exception from try catch when exception type not specified

In cases when you use a try catch block as such.
try {
//Do my work!
}
catch
{
//Handle my exception
}
Is there some way to refer to the exception object in the catch block?
ie:
try {
//Do my work!
}
catch
{
//Handle my exception
MyUndefinedExceptionObject.Message ????
}
EDIT: I don't think I was clear
enough. I am aware of how one would
typically catch exceptions using a try
catch block. What I am wondering is
given you have the ability to not
specify a type for your exception yet
declare the block is there still some
way of retrieving the exception object
in such cases? Judging by your answers
however I assume there isn't?
You'll want to catch the exception type you care about. When you do, you'll have access to all the properties of that exception.
try
{
//Do my work!
}
catch (MyExceptionType e)
{
string s = e.Message;
}
Here's a reference in MSDN, to get up to speed.
Regarding your edit: no there is no way to access the thrown exception unless the exception is explicitly specified in your catch statement.
Yes, like this:
try
{
//Do my work!
}
catch (mySpecificException myEx)
{
//Handle my exception
}
catch (Exception ex)
{
//Handle my exception
}
(Most specific to least specific)
No.
Using the bare catch indicates that you do not care about the actual exception otherwise, why not use
catch (System.Exception ex)
to catch any exception? Of course, you should only catch exceptions you will handle.
You need to indicate the specific type of exception that you are catching, and assign that to a variable.
Do that using this syntax instead:
try
{
// Do work
}
catch (MyUndefinedExceptionObject ex)
{
Debug.WriteLine(ex.Message);
}
You can also include multiple catch blocks with the type of exception altered accordingly. However, remember that you should always order them from most derived to least derived, ending with the base class for all exceptions, System.Exception.
You also should generally refrain from catching System.Exception, instead preferring only to catch the derived exceptions that you can handle in the catch block and that won't corrupt your program's state. Catching System.Exception class is a bad idea because you'll also catch exceptions that you won't be able to handle, like an OutOfMemoryException or a StackOverflowException.
Microsoft has a helpful article on best practices here: Best Practices for Handling Exceptions

Is an empty catch the same as "catch Exception" in a try-catch statement?

try {
}
catch (Exception) {
}
can I just write
try {
}
catch {
}
Is this ok in C# .NET 3.5? The code looks nicer, but I don't know if it's the same.
They are not the same.
catch (Exception) { } will catch managed exceptions only; catch { } will catch non-CLS exceptions as well: http://msdn.microsoft.com/en-gb/bb264489.aspx
An unhandled non-CLS compliant
exception becomes a security issue
when previously allowed permissions
are removed in the catch block.
Because non-CLS compliant exceptions
are not caught, a malicious method
that throws a non-CLS compliant
exception could run with elevated
permissions.
Edit: Turns out .NET 2.0+ wraps the values -- so they are the same. That's a bit of a relief!
Yes, the advantage of the first form is that you can name the exception variable and then use the object to log the exception details to file, etc...
try {
}
catch (Exception ex) {
// Log exception message here...
}
Also, it is generally a bad practice to catch the generic Exception class if you can instead catch specific exceptions (such as an IOException) using the first form.
Edit: As of C# 2.0, non-CLS-compliant exceptions can be caught in both ways.
So, yes. They are identical. A parameter-less catch clause without a Type declaration catches all Exceptions.
In the CLR 2.0, MS introduced RuntimeWrappedException, which is a CLS-compliant exception type, to encapsulate non-CLS-compliant exceptions. The C# compiler still doesn't allow you to throw them, but it can catch them with the catch (Exception) { } syntax.
This is why the C# compiler will issue warning CS1058 if you use both clauses at the same time on CLR 2.0 or later.
Thus, they are in fact identical.
Its the same, but if you put an e after Exception in your first example then you know what exception was thrown...
edit: you should never catch exception, how do you know how to handle it properly?
They are different as noted:
An unhandled non-CLS compliant exception becomes a security issue when previously allowed permissions are removed in the catch block. Because non-CLS compliant exceptions are not caught, a malicious method that throws a non-CLS compliant exception could run with elevated permissions.
You can see the difference in the IL generated:
//no (Exception)
.try L_0001 to L_0005 catch object handler L_0005 to L_000a
//with (Exception)
.try L_0001 to L_0005 catch [mscorlib]System.Exception handler L_0005 to L_000a
I guess unless you want to use the Exception in some sort, the second one is perfectly fine, though in order to use the exception in the first one, you need to declare a variable like this:
try {
}
catch (Exception e) {
//do something with e
}
Both of your examples appear like you're not doing anything with the exception data. This is generally not a good practice. But both are exactly the same since all exceptions classes are derived from System.Exception.
You should consider doing some type of logging then possibly rethrow the original exception or wrap it in a more specialized exception that your application can understand.
try
{
// Some code here
}
catch(Exception ex)
{
// Do some logging
throw;
}
OR
try
{
// Some code here
}
catch(Exception ex)
{
// Do some logging
// wrap your exception in some custom exception
throw new CustomException("Some custom error message, ex);
}
You should typically only catch exceptions that your code could handle, otherwise it should bubble up and it should eventually be caught by a global exception handler assuming you have one.
Parameter less constructor will cause handling of exception types coming from some other languages, exception which are not inherited from c# SYSTEM.EXCEPTION class.

How does Catch (object o) work?

I was reading the blog of Chris Brumme and this code was listed:
catch (object o) { .... }
There wasn't a full explanation on this line although the article I read was on general exception handling (SEH and exceptions in managed code).
How does that line above work? Exceptions are always of type Exception (or derived)? To catch ALL exceptions just omit the brackets and its contents or catch (Exception x) will do.
Thanks
That shouldn't be legal:
15.10 The try statement
When a catch clause specifies a class-type, the type shall be System.Exception or a type that derives from System.Exception.
Similarly, the only thing that C# lets you throw is an object of type System.Exception.
However,
Note: Some environments, especially those supporting multiple languages, might support exceptions that are not representable as an object derived from System.Exception, although such an exception could never be generated by C# code. In such an environment, a general catch clause might be used to catch such an exception....
The general catch clause doesn't let you catch the object, though. If you're only using C#, then I would use catch (Exception e) if I wanted to take some action on the exception's message, or log it somewhere; I would save catch for when you really don't care about the actual exception value. If you were actually depending on the general catch clause to catch things that aren't Exceptions, you should document it with a comment.
From framework 2.0 catching an Object is pointless.
Earlier you could get an exception from unmanaged code that did not derive from the Exception class, but from framework 2.0 all unmanaged exceptions are wrapped in an object derived from Exception, thus there is no longer any use for catch (Object o) or a parameterless catch.
First of all, in most languages Exception dervies from Object.
Also, depending on the language, you may throw anything; not just an object that derives from Exception.
This would allow you to catch these as well.
Exception inherits from Object.
Thus, the line will "work" (in that it catches all exceptions), but it's still not good style.
In fact, catching all exceptions regardless of type is usually a bad idea anyway.
Exception is a Object and it can be derived, BUT the catch object must be an Exception and expression are not permitted (so or an Execption or is a derived of Exception)
When the Exception is cathed it will execute the code inside the catch and just in this scope your exception object will be defined.
If u dont put code, nothing will append.
!Note if put a derived type the catch will work just if the trhow execption has got this type
example
//BLOCK ANYTHING
try
{
...do something..
}
catch
{
}
//OR
try
{
...do something..
}
catch(Exception ex)
{
...do something else..
}
<---- Here the variable ex is not defined
for custom blocking:
class MyException : Exception
{
...bla bla...
}
class OtherEx: notImplementedException
{
...foo foo..
}
try
{
}
catch(MyException ex)
{
Console.WriteLine("Is mine !");
}
catch(OtherEx ex)
{
Console.WriteLine("Is other !");
}
catch(Exeception ex)
{
Console.WriteLine("Is anything else !");
}

Thoughts on try-catch blocks

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

Categories

Resources