views:

1467

answers:

5

Is there a way to determine the exception type even know you caught the exception with a catch all?

Example:

try
{
   SomeBigFunction();
}
catch(...)
{
   //Determine exception type here
}
+1  A: 

No.

Doing so would at the very least require you to be able to access the current exception. I do not believe there is a standard way of doing this.

Once you had the exception instance, you would have to use a type inspection algorithm. C++ doesn't have inherent support for this. At best you would have to have a big if/elseif statement with dynamic_cast's to check the type.

JaredPar
+4  A: 

If you need to handle exceptions differently based on what they are, you should be catching specific exceptions. If there are groups of exceptions that all need to be handled identically, deriving them from a common base class and catching the base class would be the way to go. Leverage the power and paradigms of the language, don't fight against them!

Harper Shelby
+7  A: 

Short Answer: No.

Long Answer:

If you derive all your exceptions from a common base type (say std::exception) and catch this explicitly then you can use this to get type information from your exception.

But you should be using the feature of catch to catch as specific type of exception and then working from there.

The only real use for catch(...) is:

  • Catch: and throw away exception (stop exception escaping destructor).
  • Catch: Log an unknwon exception happend and re-throw.

Edited: You can extract type information via dynamic_cast<>() or via typid() Though as stated above this is not somthing I recomend. Use the case statements.

#include <stdexcept>
#include <iostream>

class X: public std::runtime_error  // I use runtime_error a lot
{                                   // its derived from std::exception
    public:                         // And has an implementation of what()
        X(std::string const& msg):
            runtime_error(msg)
        {}
};

int main()
{
    try
    {
        throw X("Test");
    }
    catch(std::exception const& e)
    {
        std::cout << "Message: " << e.what() << "\n";

        /*
         * Note this is platform/compiler specific
         * Your milage may very
         */
        std::cout << "Type:    " << typeid(e).name() << "\n";
    }
}
Martin York
How would that work in this case with a catch all?
JaredPar
Edited to make it clearer that you would need to catch the base exception.
Martin York
"then you can use this to get type information from your exception.". How? Via something like a dynamic_cast?
Brian R. Bondy
+5  A: 

You can actully determine type inside a catch(...), but it is not very useful:

#include <iostream>
#include <exception>

    class E1 : public std::exception {};
    class E2 : public std::exception {};

    int main() {
        try {
         throw E2();
        }
        catch( ... ) {
         try {
          throw;
         }
         catch( const E1 & e ) {
          std::cout << "E1\n";
         }
         catch( const E2 & e ) {
          std::cout << "E2\n";
         }
        }
    }
anon
A: 

If you're using Visual C++ (managed), you can use the GetType() method to get the type of exception and handle it from there.

E.g.

try
    {
        // Run the application
        Application::Run(mainForm);
    }
    catch (Exception^ e)
    {
        String^ exception_type = e->GetType()->ToString();
        throw;
    }

The string will contain something like "System.ArgumentOutOfRangeException".

Roderick