I have the following code I have simplified:
Thread two:
boost::unique_future<void> future;
TaskPtr task(new task::ReloadConfig(future));
Listener::PushTask(task);
future.wait();
try
{
future.get();
}
catch (const cfg::ConfigError& e)
{
return cmd::Result::Okay;
}
Thread two:
try
{
cfg::UpdateShared(std::shared_ptr<cfg::Config>(new cfg::Config(configFile)));
}
catch (...) // should be cfg::ConfigError
{
promise.set_exception(boost::current_exception());
return;
}
promise.set_value();
Instead of a the Cfg::ConfigError exception or one of its derived exceptions being propogated from thread two to thread one I get the following:
terminate called after throwing an instance of
'boost::exception_detail::clone_impl'
what(): std::exception
Seems this other person had similar troubles and no answer:
https://stackoverflow.com/questions/10857834/how-to-use-boostfuture-get-to-get-user-defined-exception
I also get the following error if I try to use boost::enable_current_exception:
/usr/local/include/boost/exception/exception.hpp:419:20: error: no
matching function for call to 'std::runtime_error::runtime_error()'
I can get the code working fine without exceptions, by just returning a boolean value, but this is a compromise.
I would try to do something like that in your thread two:
catch (const cfg::ConfigError& e)
{
promise.set_exception(boost::make_exception_ptr(e));
}
Otherwise if you want that current_exception() to work you have to mess with things like:
throw boost::enable_current_exception(cfg::ConfigError("meh"));
Related
I am creating an object of my class in try/catch block and want to access it in catch block in case of exception. Even if the object is created ok, I cannot access it in catch block as it declared outside the block.
try {
MyObject ob(arg1,arg2); //this can trow exception
ob.func1(); //this also can throw exception
} catch (std::exception& ex){
//I want to access ob here if it was constructed properly and get the reason why func1() failed
}
I can use nested try/catch blocks to solve this issue but is there any other way to solve this
try {
MyObject ob(arg1,arg2); //this can trow exception
try {
ob.func1(); //this also can throw exception
} catch(std::exception& ex) {
//object was constructed ok, so I can access reason/state why the operation failed
}
} catch (std::exception& ex){
//object failed to construct
}
No, you can not do this. It is not possible to access this variable from same-level catch block.
The solution is to stop using exceptions as a flow control mechanism - they are not - and use them as they are, an indication of exceptional situation - in which case it doesn't really matter what did throw.
No, you cannot access an object out of scope. But to answer this:
get the reason why func1() failed
If the object construction failed because of an exception, this means that the std::exception already contains some information about why it has failed.
So you have to do this in your code:
catch (std::exception& ex){
// object failed to construct
std::cout << ex.what() << std::endl;
}
Andrei Alexandrescu's ScopeGuard might help here:
try {
MyObject ob(arg1,arg2);
SCOPE_FAIL { /* Handler 1 */ };
ob.func1();
} catch (std::exception& ex) {
/* Handler 2 */
}
The body of SCOPE_FAIL will be executed if its scope is left via stack unwinding, that is, an exception has been thrown. Unfortunately you can't access the exception itself there, but you can access ob.
The rest of the program behaves as usual, so the execution looks like:
ob is successfully constructed;
ob.func1() is executed and throws;
/* Handler 1 */ is executed;
ob is destructed;
/* Handler 2 */ is executed.
Question:
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)? Or can I just explicitly call something like exit(EXIT_FAILURE) instead?
What I'm Currently Doing:
I'm working on a game project and am trying to figure out the best way to terminate the program in the case of an error that calls for such an action. For example, in the case the textures can't be loaded I display an error message and terminate the program.
I'm currently doing this with exceptions like so:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
return 0;
}
All but bad_alloc are my own defined exceptions derived from runtime_error.
I don't need any manual resource cleanup and I'm using std::unique_ptr for any dynamic allocation. I just need to display the error message and close the program.
Research/Alternatives to Exceptions:
I've looked up a lot of posts on SO and other places and have seen others say anything from don't use exceptions, to use exceptions but your using them wrong. I've also looked up explicitly calling something like exit().
Using exit() sounds nice but I read it won't go back through the call stack up to main cleaning everything up (if I can find this again I'll post the link). Additionally, according to http://www.cplusplus.com/reference/cstdlib/exit/ this should not be used if multiple threads are active. I do expect to be creating a second thread for a short time at least once, and an error could occur in that thread.
Not using exceptions was mentioned in some replies here in relation to games https://gamedev.stackexchange.com/questions/103285/how-industy-games-handle-their-code-errors-and-exceptions
Use exceptions was discussed here: http://www.quora.com/Why-do-some-people-recommend-not-using-exception-handling-in-C++
There are a number of other sources I've read but those were the most recent I looked at.
Personal Conclusion:
Due to my limited experience of working with error handling and using exceptions, I'm not sure if I'm on the right track. I've chosen the route of using exceptions based on the code I posted above. If you agree that I should tackle those cases with exceptions, am I using it correctly?
It's generally considered good practice to let all exceptions propagate through to main. This is primarily because you can be sure the stack is properly unwound and all destructors are called (see this answer). I also think it's more organised to do things this way; you always known where your program will terminate (unless the program crashes). It's also facilitates more consistent error reporting (a point often neglected in exception handling; if you can't handle the exception, you should make sure your user knows exactly why). If you always start with this basic layout
int main(int argc, const char **argv)
{
try {
// do stuff
return EXIT_SUCCESS;
} catch (...) {
std::cerr << "Error: unknown exception" << std::endl;
return EXIT_FAILURE;
}
}
then you won't go far wrong. You can (and should) add specific catch statements for better error reporting.
Exceptions when multithreading
There are two basic ways of executing code asynchronously in C++11 using standard library features: std::async and std::thread.
First the simple one. std::async will return a std::future which will capture and store any uncaught exceptions thrown in the given function. Calling std::future::get on the future will cause any exceptions to propagate into the calling thread.
auto fut = std::async(std::launch::async, [] () { throw std::runtime_error {"oh dear"}; });
fut.get(); // fine, throws exception
On the other hand, if an exception in a std::thread object is uncaught then std::terminate will be called:
try {
std::thread t {[] () { throw std::runtime_error {"oh dear"};}};
t.join();
} catch(...) {
// only get here if std::thread constructor throws
}
One solution to this could be to pass a std::exception_ptr into the std::thread object which it can pass the exception to:
void foo(std::exception_ptr& eptr)
{
try {
throw std::runtime_error {"oh dear"};
} catch (...) {
eptr = std::current_exception();
}
}
void bar()
{
std::exception_ptr eptr {};
std::thread t {foo, std::ref(eptr)};
try {
// do stuff
} catch(...) {
t.join(); // t may also have thrown
throw;
}
t.join();
if (eptr) {
std::rethrow_exception(eptr);
}
}
Although a better way is to use std::package_task:
void foo()
{
throw std::runtime_error {"oh dear"};
}
void bar()
{
std::packaged_task<void()> task {foo};
auto fut = task.get_future();
std::thread t {std::move(task)};
t.join();
auto result = fut.get(); // throws here
}
But unless you have good reason to use std::thread, prefer std::async.
There's nothing wrong with catching unrecoverable errors and shutting down your program this way. In fact, it's how exceptions should be used. However, be careful not to cross the line of using exceptions to control the flow of your program in ordinary circumstances. They should always represent an error which cannot be gracefully handled at the level the error occurred.
Calling exit() would not unwind the stack from wherever you called it. If you want to exit cleanly, what you're already doing is ideal.
You have already accepted an answer, but I wanted to add something about this:
Can I just explicitly call something like exit() instead?
You can call exit, but (probably) shouldn't.
std::exit should be reserved for situations where you want to express "exit right now!", not simply "application has nothing left to do".
As an example, if you were to write a controller for a laser used in cancer treatments, your first priority in case something went wrong would be to shut down the laser and call std::exit - or possibly std::terminate (to ensure any side effects of a hanging, slow or crashing application do not kill a patient).
Similar to how exceptions should not be used for controlling application flow, exit should not be used to stop the application in normal conditions.
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)?
Yes. This is the reason for using exceptions. An error occurred deep down in the code and something at a higher level will handle it. In your case, at the highest level.
There are arguments for/against exceptions vs. error codes, and this is a good read:
Exceptions or error codes
Can I just explicitly call something like exit() instead?
You can, but you may end up duplicating your logging code. Also, if in the future you decide that you want to handle an exception differently you will have to change all your exit calls. Imagine you wanted a different message, or to fall back on an alternative process.
Another similar question:
Correct usage of exit() in c++?
You also have a flaw in your approach as you don't handle all (C++) exceptions. You want something like this:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
catch (...)
{
// overload?
Notification::showErrorMessage("ERROR: Unhandled");
return 1;
}
return 0;
}
If you don't handle all* exceptions you could have the game terminate without telling you anything useful.
You can't handle ALL exceptions. See this link:
C++ catching all exceptions
From the documentation:
[[noreturn]] void exit (int status);
Terminate calling process
Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Control is returned to the host environment.
Note that objects with automatic storage are not destroyed by calling exit (C++).
If status is zero or EXIT_SUCCESS, a successful termination status is returned to the host environment.
If status is EXIT_FAILURE, an unsuccessful termination status is returned to the host environment.
Otherwise, the status returned depends on the system and library implementation.
For a similar function that does not perform the cleanup described above, see quick_exit.
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
}
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)
Hya advance users of SO,
First of all I am new to C++, so pardon me if I don't make myself clear asking question. I've seen a example of exception handling, but couldn't figure out what's happening here :(
http://codepaste.net/zqsrnj
or
enum ErrorCode {…}; // this is exception class
ErrorCode dispatcher() {
try {
throw; // what is thrown here in function?, if rethrow what is rethrown?
}
catch (std::bad_alloc&) {
return ErrorCode_OutOfMemory;
}
catch (std::logic_error&) {
return ErrorCode_LogicError;
}
catch (myownstdexcderivedclass&) {
return ErrorCode_42;
}
catch(...) { // this will handle the above throw in try block of dispatcher
return ErrorCode_UnknownWeWillAllDie;
}
}
ErrorCode apifunc() {
try {
// foo() might throw anything
foo();
}
catch(...) {
// dispatcher rethrows the exception and does fine-grained handling
return dispatcher();
}
return ErrorCode_Fine; //
}
ErrorCode apifunc2() {
try {
// bar() might throw anything
bar();
}
catch(...) {
return dispatcher();
}
return ErrorCode_Fine;
}
Can anyone explain this line by line or overall what's happening here, how control is flowing? Any help is very much appreciated, so thanks a lot.
apifunc() and apifunc2() translate exceptions into error codes, using the dispatcher() function.
Basically, what happens is as follows:
apifunc() (and similarly apifunc2()) attempts to call a function foo(). If foo() throws an exception, then the catch block will call dispatcher() to get the error code corresponding to the exception, and then returns that error code. If foo() doesn't throw, apifunc() returns ErrorCode_Fine indicating no error.
dispatcher() works by re-throwing the last exception thrown, i.e. the one foo() threw. dispatcher() then checks which exception was thrown using the catch blocks, and returns the correct error code. For example, if foo() threw std::bad_alloc, then that catch-block will be executed and return ErrorCode_OutOfMemory;.
Why would someone do this?
Exceptions are not necessarily binary compatible across different compilations (compilers, compiler flags, and so on), so translating exceptions to error codes is more portable across module boundaries.
When foo() throws an exception during its execution, the exception is caught in the apifunc() wrapper whose catch clause invoke the dispatcher() method. There the "current" exception is rethrown (that's the empty throw statement in the dispatcher() method) and caught again. Then the different catch clauses (bad_alloc, logic_error, myownstdexcderivedclass ... returns a sepcific error code than will be returned to the outside world.
The last catch(...) clause ensures that no exception will ever be thrown to the callers of apifunc().