Getting the exception object within catch(...)

J

Jacek Dziedzic

Hi!

In my main() function I have a last-resort exception construct that
looks
like this:

int main() {
try {
// ... program code
}
catch(...) { // catch every exception
std::cout << "An exception occured!" << std::endl;
};
};

It works fine, but I never know *which* exception has occured.
I seem to remember you can catch an exception object rather than
an exception class, and then, having the precise object you could
get the name that's stored somewhere inside it. But the "..." seems
to get in the way for me. Is there a way to catch a precise exception
object with catch(...)? Or a workaround for that?

tia,
- J.
 
C

Cy Edmunds

Jacek Dziedzic said:
Hi!

In my main() function I have a last-resort exception construct that
looks
like this:

int main() {
try {
// ... program code
}
catch(...) { // catch every exception
std::cout << "An exception occured!" << std::endl;
};
};

It works fine, but I never know *which* exception has occured.
I seem to remember you can catch an exception object rather than
an exception class, and then, having the precise object you could
get the name that's stored somewhere inside it. But the "..." seems
to get in the way for me. Is there a way to catch a precise exception
object with catch(...)? Or a workaround for that?

tia,
- J.
Sure:

#include <exception> // for std::exception

int main() {
try {
// ... program code
}
catch(const std::exception &e) // catch any standard exception
{
std::cout << e.what() << '\n';
}
catch(...) { // catch any other exception
std::cout << "An exception occured!" << std::endl;
}
};

If you have any exception classes you have written yourself you should
derive them from std::exception so this will work. One tiny point:
std::exception::what is a virtual function which you may override if you
wish. But if you do, make sure you don't declare the catch phrase as:

catch (std::exception e) // bad idea

because this will bit slice down to a plain jane std::exception and your
function won't get called.
 
V

Victor Bazarov

Jacek Dziedzic said:
In my main() function I have a last-resort exception construct that
looks
like this:

int main() {
try {
// ... program code
}
catch(...) { // catch every exception
std::cout << "An exception occured!" << std::endl;
};
};

It works fine, but I never know *which* exception has occured.

'catch' with ellipsis will catch them all and it is, as you said,
the last resort. You don't get to know what exception was caught.
I seem to remember you can catch an exception object rather than
an exception class,

You always catch an object.
and then, having the precise object you could
get the name that's stored somewhere inside it. But the "..." seems
to get in the way for me. Is there a way to catch a precise exception
object with catch(...)? Or a workaround for that?

There is no way to know what exception triggered the 'catch_all'
clause unless you re-throw it and catch it again somehow differently:

void thrower()
{
throw 42;
}

#include <iostream>

void foo()
{
try
{
thrower();
}
catch(...)
{
std::cout << "caught something...\n";
throw;
}
}

int main()
{
try
{
foo();
}
catch(int i)
{
std::cout << "caught int(" << i << ")\n";
}
catch(...)
{
std::cout << "caught something again...\n";
}
return 0;
}


Now, if in your 'main' you re-throw the exception you caught, you can
get the environment report it to you. Of course, in that case you will
usually get something like "Uncaught exception blah! Abnormal program
termination!", but since you have caught it already, you get a chance
to close everything that is still open by the time 'catch(...)' is
entered.

Victor
 
J

jeffc

Jacek Dziedzic said:
Hi!

In my main() function I have a last-resort exception construct that
looks
like this:

int main() {
try {
// ... program code
}
catch(...) { // catch every exception
std::cout << "An exception occured!" << std::endl;
};
};

It works fine, but I never know *which* exception has occured.
I seem to remember you can catch an exception object rather than
an exception class, and then, having the precise object you could
get the name that's stored somewhere inside it. But the "..." seems
to get in the way for me. Is there a way to catch a precise exception
object with catch(...)? Or a workaround for that?

Normally, you don't really care about the object. Yes, you need one
technically, but all the information you need is in the type of the class
itself. The object can be totally empty.
class Exception1{};
class Exception 2{};
int main()
{
try
{
throw Exception1();
}
catch(Exception1)
{
std::cout << "Exception1 occurred" << std::endl;
}
catch(Exception2)
{
std::cout << "Exception2 occurred" << std::endl;
}
}
 
A

Alf P. Steinbach

Hi!

In my main() function I have a last-resort exception construct that
looks
like this:

int main() {
try {
// ... program code
}
catch(...) { // catch every exception
std::cout << "An exception occured!" << std::endl;
};
};

It works fine, but I never know *which* exception has occured.
I seem to remember you can catch an exception object rather than
an exception class, and then, having the precise object you could
get the name that's stored somewhere inside it. But the "..." seems
to get in the way for me. Is there a way to catch a precise exception
object with catch(...)? Or a workaround for that?

Cy Edmunds and others have already answered the real question.

Now here's an answer to the literal question.

In many cases (actually, most cases of real software) you will have to
deal with non-standard exceptions of various kinds from a number of libraries.
Using try-catch-catch-catch everywhere is then redundant and a maintainance
nightmare. So instead you'd like to use catch(...) and _translate_ that
exception, whatever it may be, to a common form.

In standard C++ you can do that by rethrowing the exception and recatching
the exception within the catch(...), where this rethrowing and recatching is
performed by a common exception translation function (which must know about
all the most common kinds of exceptions in the application).

This technique does not work with some older compilers. In particular, a
compiler bug in Visual C++ prevented using this technique with earlier
incantations of that compiler.
 

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

Members online

No members online now.

Forum statistics

Threads
474,148
Messages
2,570,838
Members
47,385
Latest member
Joneswilliam01

Latest Threads

Top