Why can I not catch my exception? - c++

I have following function that catches the system-exception of a ComObject and throws my own exception off:
int TReader::ExecSQL(...) {
try {
// ...
} catch (Comobj::EOleException& e) {
throw myDBError("TReader::Open", "TReader", e.Message);
}
// ...
}
I can not catch my own exception, getting always "Exception unknown!"! Why?
void main() {
try {
ExecSQL(...);
} catch(myDBError& e) {
log(e.Message);
} catch(...) {
log("Exception unknown!");
}
}

Use catch(const myDBError& e) { instead.
An anonymous temporary cannot bind to a non-const reference, so a throw will not be intercepted at the current catch site.

If try-catch block generates not Comobj::EOleException, but something else, that may be problem.
Also check, maybe myDBError constructor generates another exception, with another type :-)
That would be funniest explanation, why you can't catch myDBError, but still catch something :-)

Related

How to use an exception outside catch statement

I have a function that may throw an exception of a variable type, but all inheriting from std::exception:
int errorCheck(int a)
{
if(a < 0)
throw a_too_small();
if(a>10)
throw a_too_big();
return a*2;
}
I want to handle this exception using Qt's SIGNAL/SLOT mechanism.
try {
errorCheck(a);
} catch(std::exception &e) {
emit errorSignal(e);
}
If the signature of errorSignal is errorSignal(std::exception e), then the original exception object is sliced and its type is lost.
If the signature is errorSignal(std::exception &e) on the other hand, the exception e leaves the catch scope, and I believe this is not allowed.
What's the cleanest solution to handle this problem?
If using C++11 is possible, you can try to use std::exception_ptr:
try {
...
} catch (...)
std::exception_ptr except = std::current_exception();
emit signal(except);
}
Then in your slot:
void myslot(std::exception_ptr e) {
try {
if (e) {
std::rethrow_exception(e);
}
} catch (...) {
...
}
}
How about making the errorSignal function signal/slot work by reference? something like errorSignal(std::exception& e)? Do that with Qt::DirectConnection too to avoid event queuing, with something like:
connect(someWidget,SomeWidget::errorSignal&,this,MainWindow::handleError&,Qt::DirectConnection);

Nested catch operators

I need catch exceptions that are maybe thrown by code in try...catch construction, and do something depending on exception type. But also I want do some code if any exception are thrown.
I did so:
try
{
// code
}
catch (...)
{
try
{
throw;
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
// here is code that are executed if any exception are thrown
}
My code works, but I want to know whether the Standard says anything about it.
Maybe is there any better method?
UPD: Sorry for the slow answers to comments. Simple, English is a second language for me.
UPD: I think that code from AdelNick or second code from Steve Jessop or second code from David Rodríguez - dribeas are right for me.
Your approach is bad, because the // here is code that are executed if any exception are thrown part won't be executed if neither of exc1 or exc2 branch catch the exception. Your code is an equivalent version of the following:
try
{
// code
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
// here is code that are executed if any exception are thrown
The C++ language does not support a finally block, if that's what you're after. That is because an object's destructor is responsible for freeing resources, not a finally block. Here is Stroustrup's explanation of the topic.
You should write:
try
{
// code
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
catch (...)
{
// here is code that are executed if any *other* exception are thrown
}
If you want particular code to be executed as part of all three cases then you have two options: call it in all three places, or do something like this:
bool threw = true;
try
{
// code
threw = false;
}
catch (exc1)
{
// handling
}
catch (exc2)
{
// handling
}
catch (...) {
}
if (threw) {
// here is code that are executed if any exception are thrown
}
I would change the code order as following:
try
{
try
{
// code
}
catch (exc1)
{
// handling
throw; // edited. was: throw exc1;
}
catch (exc2)
{
// handling
throw; // edited. was: throw exc2;
}
}
catch(...)
{
// here is code that are executed if any exception are thrown
}
as it works if any other type of exception is thrown (not only exc1 or exc2). Also if the code common for all exceptions is the resource releasing, consider using RAII principle instead).
Looking at the comments it seems that you may be expecting something that won't happen, and that has already been discussed in other answers. But it could be a misunderstanding on our side. If the code inside the try can only throw one of exc1 or exc2 then yes, it will do what you expect.
From the comment update, it seems that the intention was to handle any exception, including those that are neither exc1 nor exc2. For that purpose, the code won't do what is expected and exc3 will propagate outside of the nested trys. Just flatten the two levels and add a catch (...) at the end.
From here on the answer was based on a false assumption about the question.
The pattern of rethrowing is supported by the standard and used commonly in situations where the handling of the exceptions in different contexts is the same to avoid code duplication:
void processException() {
// implement exception handling in all contexts
try {
throw;
} catch (exceptionType1 const & ex1) {
} catch (exceptionType2 const & ex2) {
// } catch (...) {
}
}
void f() {
try {
something();
} catch (...) {
processException();
}
}
void g() {
try {
anotherThing();
} catch (...) {
processException();
}
}
If the code to handle the exceptions is not going to be centralized for different functions, that pattern may complicate the code more than you need. You could consider a single try/catch with an extra control variable:
bool success = false;
try {
doSomething();
success = true;
} catch (exception1 const & ex1) {
...
} catch (exception2 const & ex2) {
...
// } catch (...) {
}
if (!success) {
// common code to all exceptions
}

How to avoid writing repeated code in catch blocks?

I am using QT 4.8 (C++) for desktop application project, and writing exception handling which is as follows :
void callerMethod()
{
try
{
method1();
}
catch(Exception1& e)
{
// display critcal error message
// abort application
}
catch(std::Exception& e)
{
// print exception error message
}
catch(...)
{
// print unknown exception message
}
}
void method1()
{
try
{
// some initializations
// some operations (here exceptions can occur)
// clean-up code (for successful operation i.e no exception occurred)
}
catch(Exception1& e)
{
// clean-up code
throw e;
}
catch(Exception2& e)
{
// clean-up code
throw e;
}
catch(Exception3& e)
{
// clean-up code
throw e;
}
catch(...)
{
// clean-up code
throw;
}
}
So my question do I need to write the clean-up code in every catch block?
Is there any way I can avoid writing repeated code?
NOTE:: [ In method1() ] I want to re-throw exceptions which occurred
to my caller.So I can not catch them in single catch block,
because then type information will be lost.
Method1 can be much simplified by two concepts:
RAII. Put any clean-up code into destructors, and the clean-up code will be centralized.
Use the unqualified throw, and you won't need to know about the type of exception thrown.
So, method1() should look like:
void method1()
{
// some initializations of RAII objects
// some operations (here exceptions can occur)
}
The first catch clause in callerMethod can be removed if you derive Exception1 from std::exception, since the what() method is virtual.
You should throw exceptions as low as possible and catch them as high as possible in the call chain. This automatically leads to less code duplication, and centralizes error handling. You are throwing/catching all in one place, which seems a bit ... forced.
I often do this kind of thing (especially for program-ending exceptions:
int main()
try
{
function_calls_that_may_throw();
// ...
}
catch(my_exception& e)
{
e.do_exception_stuff();
}
catch(std::exception& e)
{
std::cout << e.what();
}
catch(...)
{
std::cout << "Something bad happened.\n";
}
This is only possible for throwing exceptions you don't plan on handling better or retrying the failed operation or something.
The pro of this approach is that all/most error handling code is at the top-level of your program, and all the functions in the call chain don't have to worry one bit about this stuff, all they do is throw an exception when they feel like it.
If all your clean up code is totally identical, you can do everything in your catch (...) block:
try {
// code
} catch (...) {
// cleanup
throw;
}
If your code varies slightly, you can always call a cleanup function:
try {
// code
} catch (exc1 ex) {
cleanup(args);
// exc1 specific
throw;
} catch (exc2 ex) {
cleanup(args);
// exc2 specific
throw;
} catch (...) {
cleanup(args);
throw;
}

Will exception thrown in catch block be caught by later catch blocks?

Consider the following C++ code:
try {
throw foo(1);
} catch (foo &err) {
throw bar(2);
} catch (bar &err) {
// Will throw of bar(2) be caught here?
}
I would expect the answer is no since it is not inside the try block and I see in another question the answer is no for Java, but want to confirm C++ is also no. Yes, I can run a test program, but I'd like to know the language definition of the behavior in the remote case that my compiler has a bug.
No. Only exceptions thrown in the associated try block may be caught by a catch block.
No, It won't, An enclosing catch block upwards the hierarchy will be able to catch it.
Sample Example:
void doSomething()
{
try
{
throw foo(1);
}
catch (foo &err)
{
throw bar(2);
}
catch (bar &err)
{
// Will throw of bar(2) be caught here?
// NO It cannot & wont
}
}
int main()
{
try
{
doSomething();
}
catch(...)
{
//Catches the throw from catch handler in doSomething()
}
return 0;
}
No, a catch block handles the nearest exception, so if you try ... catch ( Exception &exc ) ... catch ( SomethingDerived &derivedExc ) the exception will be handled in the &exc block
You might achieve the desired behaviour by exception delegation to the calling method

Which is correct? catch (_com_error e) or catch (_com_error& e)?

Which one should I use?
catch (_com_error e)
or
catch (_com_error& e)
The second. Here is my attempt at quoting Sutter
"Throw by value, catch by reference"
Learn to catch properly: Throw exceptions by value (not pointer) and
catch them by reference (usually to const). This is the combination
that meshes best with exception semantics. When rethrowing the same
exception, prefer just throw; to throw e;.
Here's the full Item 73. Throw by value, catch by reference.
The reason to avoid catching exceptions by value is that it implicitly makes a copy of the exception. If the exception is of a subclass, then information about it will be lost.
try { throw MyException ("error") }
catch (Exception e) {
/* Implies: Exception e (MyException ("error")) */
/* e is an instance of Exception, but not MyException */
}
Catching by reference avoids this issue by not copying the exception.
try { throw MyException ("error") }
catch (Exception& e) {
/* Implies: Exception &e = MyException ("error"); */
/* e is an instance of MyException */
}
Personally, I would go for the third option:
catch (const _com_error& e)
Also, note that, when using MFC, you may have to catch by pointer. Otherwise, #JaredPar's answer is the way you should normally go (and hopefully never have to deal with things that throw a pointer).
Definitely the second. If you had the following:
class my_exception : public exception
{
int my_exception_data;
};
void foo()
{
throw my_exception;
}
void bar()
{
try
{
foo();
}
catch (exception e)
{
// e is "sliced off" - you lose the "my_exception-ness" of the exception object
}
}