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
}
Related
I would like to know if there is an else statement, like in python, that when attached to a try-catch structure, makes the block of code within it only executable if no exceptions were thrown/caught.
For instance:
try {
//code here
} catch(...) {
//exception handling here
} ELSE {
//this should execute only if no exceptions occurred
}
The concept of an else for a try block doesn't exist in c++. It can be emulated with the use of a flag:
{
bool exception_caught = true;
try
{
// Try block, without the else code:
do_stuff_that_might_throw_an_exception();
exception_caught = false; // This needs to be the last statement in the try block
}
catch (Exception& a)
{
// Handle the exception or rethrow, but do not touch exception_caught.
}
// Other catches elided.
if (! exception_caught)
{
// The equivalent of the python else block goes here.
do_stuff_only_if_try_block_succeeded();
}
}
The do_stuff_only_if_try_block_succeeded() code is executed only if the try block executes without throwing an exception. Note that in the case that do_stuff_only_if_try_block_succeeded() does throw an exception, that exception will not be caught. These two concepts mimic the intent of the python try ... catch ... else concept.
Why not just put it at the end of the try block?
Is it a way to avoid code duplication (FinalAction function call in all catch blocks and in a try one)?
try
{
// some actions including creation of new objects
FinalAction();
}
catch (const Exception1& ex1)
{
ProcessException1(ex1);
FinalAction();
}
catch (const Exception2& ex2)
{
ProcessException2(ex2);
FinalAction();
}
// ...
catch (const ExceptionN& exN)
{
ProcessExceptionN(exN);
FinalAction();
}
catch (...)
{
ProcessUnknownException();
FinalAction();
}
Update: FinalAction() should be called before the destructors of the objects created in the try block. So simple solution like the following one doesn't work here.
try
{
// some actions including creation of new objects
}
catch (const Exception1& ex1)
{
ProcessException1(ex1);
}
catch (const Exception2& ex2)
{
ProcessException2(ex2);
}
// ...
catch (const ExceptionN& exN)
{
ProcessExceptionN(exN);
}
catch (...)
{
ProcessUnknownException();
}
FinalAction();
Some more information about FinalAction: it doesn't throw and it doesn't clean any resources allocated in the try block.
Although your question is not an exact duplicate, the answer to this question is appropriate.
What you seem to bee asking for is the equivalent of a finally-clause in C++ and the answer is that in C++ this is normally solved through RAII.
I won't repeat the quite extensive answer that was given in the linked SO question, but in summary you make sure that cleanup of resources is done in a destructor. It is likely that your FinalAction() is the one that is cleaning up resources right now.
I don't know to which classes do ProcessExceptionX and FinalAction belong or what does ProcessException do, but maybe you could have just one ProcessException that gets a parameters and executes FinalAction, e.g.:
...
try {
FinalAction();
}
catch (const Exception1& ex1) {
ProcessException(ex1);
}
...
void ProcessException (Exception e) {
// do things
FinalAction();
}
The simplest thing to do is just call it after the try block.
bool success = false;
try
{
// some actions including creation of new objects
FinalAction();
success = true;
}
catch (const Exception1& ex1)
{
ProcessException1(ex1);
}
if (!success)
FinalAction();
However it's pretty dubious to be doing this instead of using a class to manage whatever resource you're cleaning up with FinalAction.
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;
}
I have a code:
void Engine::count(const std::set<boost::filesystem3::path>& files)
{
for (auto e : files)
{
try
{
count_(e);
}
catch (const Bad_formatting& ) // Here I'm trying to catch this exception
{//but debugger never stops on this line even though breakpoint is set
throw; // and re-throw it
}
}
}
Then there is this count_ function:
void Engine::count_(const boost::filesystem3::path& file)
{
// and somewhere along this lines I'm throwing Bad_Formatting:
if (something)
{
}
else
{
throw Bad_formatting(file,"No end of multicomment found.");
}
}
But after throwing this exception, I'm getting dialog telling me that my application requested runtime to terminate in an unusual way...
The exception is never cought. Why? Does the fact that both of those fncs are static has anything to do with it? Or the fact that I'm using Qt?
EDIT:
This is the code which calls count:
try
{
Engine::count(files);
}
catch (const Bad_formatting& e)
{
QMessageBox::warning(nullptr,"Bad Formatting",msg);
}
////
struct Bad_formatting : public std::runtime_error
{
private:
boost::filesystem3::path file_name_;
public:
Bad_formatting(boost::filesystem3::path file_name,
const char* msg):std::runtime_error(msg),
file_name_(file_name)
{
}
const boost::filesystem3::path& file_name()const
{
return file_name_;
}
~Bad_formatting()throw()
{/*eb*/}
};
From the code you show you
throw an exception;
catch it;
rethrow it;
never catch it again.
Item 4 seems to be the important part.
What compiler/toolchain/debugger are you using? If you are using GCC you can use the catch throw and catch catch commands to add breakpoints on exception throwing/catching.
As of the possible reasons that it is not being caught, if the only code in the catch block is a throw, the compiler might have optimized the whole block away. Consider adding any instruction to the block (note any might require some instruction with actual side effects, or the compiler might also optimize that away)
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