4

I'm just trying to understand this a little better.

I understand there are many different exception types, and according to some reading I've done, all exception types are caught by Exception. First of all, can I be assured that this is true?

try{
    ...
}
catch(Exception x){
    //No matter what fails in the try block, x 
    //will always have a value since all exception
    //types are caught under Exception? I guess
    //What I really want to know, is will this ever
    //Fail?
}
catch(SystemException x){
    //This code will never execute since all 
    //exceptions are caught in the first catch?
}

Next, how does this catching hierarchy work? If Exception is at the top, is every other exception type one level under Exception, or are there multiple type tiers, like if Exception is the parent of ExceptionSomething, which is the parent of ExceptionSomethingElse?

addendum:

Or if we have code like this:

try{
    ...
}
catch(SystemException x){
    //If there is an exception that is not a SystemException
    //code in this block will not run, right (since this is 
    //looking specifically for SystemExceptions)?
}
sooprise
  • 22,657
  • 67
  • 188
  • 276

6 Answers6

8

It actually depends on your .NET version and configuration. In C++/CLI you can throw anything; it doesnt have to be an Exception. In 1.1 (IIRC) ou could only catch these with a catch block like:

catch {...}

Which isn't very helpful - you can't see what happened. In 2.0 (IIRC) by default such exceptions are automatically wrapped up inside a dummy RuntimeWrappedException subclass. However, for compatibility you can turn this off. I beg you: don't :)

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • If I don't add any code that throws anything crazy, catching only for Exception should be good enough? – sooprise Apr 14 '11 at 18:37
  • @sooprise yes; in any sane code, catching Exception is fine; but only do that for logging etc; and remember to `throw`, not `throw ex` to re-throw. – Marc Gravell Apr 14 '11 at 18:39
4

Yes, this works because all standard exceptions inherit from Exception.

Your code will work but you'll need to put the handler for Exception after all specialized exception types. (The first matching handler will execute.)

Exceptions that do not inherit from Exception would not be caught because they are not the specified type. But the .NET exception classes all inherit from this base class.

Some people don't think it's a good idea but I generally only catch Exception, unless I want special handling for a particular exception type.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
2

Yes, Exception is inherited from the Object class, and all exceptions are inherited from the Exception class.

The above link will show you the hierarchy of all the exceptions.

System.Object 
  System.Exception
    Microsoft.Build.BuildEngine.InternalLoggerException
    Microsoft.Build.BuildEngine.InvalidProjectFileException
    Microsoft.Build.BuildEngine.InvalidToolsetDefinitionException
    Microsoft.Build.BuildEngine.RemoteErrorException
    ...

Some of these exception, like the SystemException you mentioned have further exceptions inherited from them, but they all still inherit from the Exception class:

System.Object 
  System.Exception
    System.SystemException
      Microsoft.SqlServer.Server.InvalidUdtException
      System.AccessViolationException
      System.Activities.ValidationException
      System.AppDomainUnloadedException
      System.ArgumentException
      System.ArithmeticException
      ...
Seth Moore
  • 3,575
  • 2
  • 23
  • 33
2

To answer the second part of your question, an example of an exception hierarchy from the .Net Framework:

ArgumentNullException inherits from
ArgumentException inherits from
SystemException  inherits from
Exception     

You should try to handle the most specific case that you can.

try{
    //something
}
catch(ArgumentNullException ex){
    //handle ArgumentNullException
}
catch(SystemException ex1)
{
    //handle other kinds of SystemException
    if(IDontWantToHandleThisExceptionHere(ex1))
    {
        throw;//  not throw new Exception(ex1);
    }
}
Grokodile
  • 3,881
  • 5
  • 33
  • 59
1

The latter, exceptions can inherit from the base Exception class or any other class that inherits the base class.

For example: SqlException inherits from DbException which inherits from ExternalException which inherits from SystemException which finally inherits from Exception.

Chris Van Opstal
  • 36,423
  • 9
  • 73
  • 90
1

Yes, all exception types are inherited from exception.

And, the way inheritance works, you can have multiple level of inheritance

MyAppException : Exception {
}

MyAppFileNotFoundException : MyAppException {
}

This is usually used to have different behavior with different types of exceptions

try {
     openfile('thisFileDoesNotExist.txt');
}
catch (MyAppFileNotFoundException ex)
{
      //warn the user the file does not exist
}
catch (Exception ex)
{
      //warn the user an unknown error occurred, log the error, etc
}
Ortiga
  • 8,455
  • 5
  • 42
  • 71