I'm trying to implement something similar to the following in my VS 2008 C++/MFC project:
class myClass()
{
public:
myClass()
{
//Do work... check for errors
if(var < 0)
{
//Error
TCHAR buff[1024];
_snwprintf_s(buff, SIZEOF(buff), L"ERROR: The value of var=%d", var);
throw buff;
}
}
};
__try
{
//Begin using class above
//The class member may be also defined on the global scale, thus
//the following exception trap may happen via SetUnhandledExceptionFilter
myClass mc;
}
__except(1)
{
//Process unhandled exception
//But how to trap the string passed in 'throw' above?
}
But I can't seem to catch the "string" that I'm passing in the throw statement.
Use std::runtime_error, eg:
#include <stdexcept>
class myClass()
{
public:
myClass()
{
//Do work...check for errors
if(var < 0)
{
//Error
char buff[1024];
_snprintf_s(buff, SIZEOF(buff), "ERROR: The value of var=%d", var);
throw std::runtime_error(buff);
}
}
};
try
{
//Begin using class above
myClass mc;
}
catch (const std::runtime_error &e)
{
//Process unhandled exception
//e.what() will return the string message ...
}
You can try something like this, for example:
struct CustomError {
CustomError(std::string& info)
: m_info(info) {}
std::string m_info;
};
/*...*/
int main() {
try {
std::string info = "yo dawg";
throw CustomError(info);
}
catch (CustomError& err) {
std::cout << "Error:" << err.m_info;
}
}
Character buffer way:
#include <string>
#include <iostream>
void DoSomething()
{
throw "An error occurred!";
}
int main()
{
try
{
DoSomething();
std::cout << "Nothing bad happened" << std:endl;
}
catch(const char &err)
{
std::cerr << err << std::endl;
}
}
, or std::string way:
#include <string>
#include <iostream>
void DoSomething()
{
throw std::string("An error occurred!");
}
int main()
{
try
{
DoSomething();
std::cout << "Nothing bad happened" << std:endl;
}
catch(std::string &err)
{
std::cerr << err << std::endl;
}
}
Related
I am Implementing some program error exception catching and it's not getting to work properly thus I have seen any error in my code and compiler is also not showing any warnings and error.
The programs build successfully but ignored the exceptions.
#include <iostream>
#include <string>
using namespace std;
void wrongUsage()
{
bool erroCode = true;
bool errorMessge = true;
bool stringError = true;
if(erroCode)
{
throw 7;
}else if (errorMessge)
{
throw "Something went wrong in Character message";
}else if(stringError)
{
throw string ("Something else wrong happened in the string area");
}
}
void programErrorExceptions()
{
void wrongUsage();
}
int main()
{
try {
programErrorExceptions();
}
catch (int err)
{
cout << "Code Exception occurred: " << err << '\n';
}
catch (char const *err)
{
cout << "Msg Exception occurred: " << err << '\n';
}
catch (string &err)
{
cout << "Strmsg Exception occurred: " << err << '\n';
}
return 0;
}
correct the following
void programErrorExceptions()
{
void wrongUsage();
}
to
void programErrorExceptions()
{
wrongUsage();
}
I am trying to call the future::get() function from the function started using the std::async function. In the async function I am throwing so that I can catch the exception in the future::get() call. However, I get an exception in the get() call that is not caught in the catch bloc and the program crashes with unhandeld exception. What am I missing ?
#include "stdafx.h"
#include <iostream>
#include <future>
void AsyncMethodThrowsExceptionTest();
void AsyncMethodThrowsException();
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
AsyncMethodThrowsExceptionTest();
return 0;
}
void AsyncMethodThrowsExceptionTest()
{
std::future<int> executionFuture;
try
{
executionFuture = async(launch::async, AsyncMethodThrowsException);
}
catch(...)
{
cout << "caught ex [1]";
}
std::future_status::future_status status;
status = executionFuture.wait_for(std::chrono::milliseconds(500u));
if(status == std::future_status::deferred)
{
cout << "AsyncMethodThrowsException has not started";
}
else if(status == std::future_status::timeout)
{
cout << "AsyncMethodThrowsException timed out";
}
else if(status == std::future_status::ready)
{
cout << "AsyncMethodThrowsException successfully completed";
try
{
if(executionFuture.valid())
{
executionFuture.get();
}
}
catch(const std::future_error& ex)
{
cout << "AsyncMethodThrowsExceptionTest catch block";
}
}
}
void AsyncMethodThrowsException()
{
throw(new exception("Exception from AsyncMethodThrowsException"));
}
Not only are you throwing a pointer to a std::exception in AsyncMethodThrowsException (there's no reason to do this), you're both catching a reference to an exception not a pointer, and a reference to a child class of std::exception at that; std::future::get() throws the exact exception thrown in the called function, not a std::future_error.
There are a couple of other syntax issues:
std::future<int> executionFuture should be std::future<void> executionFuture
std::future_status::future_status status should be std::future_status status.
std::exception does not have a constructor that takes a char const* or a std::string, this might be a compiler extension.
To sum things up:
#include <iostream>
#include <future>
void AsyncMethodThrowsExceptionTest();
void AsyncMethodThrowsException();
using namespace std;
int main()
{
AsyncMethodThrowsExceptionTest();
}
void AsyncMethodThrowsExceptionTest()
{
std::future<void> executionFuture;
try
{
executionFuture = async(launch::async, AsyncMethodThrowsException);
}
catch (...)
{
cout << "caught ex [1]";
}
std::future_status status = executionFuture.wait_for(std::chrono::milliseconds(500u));
if (status == std::future_status::deferred)
{
cout << "AsyncMethodThrowsException has not started";
}
else if (status == std::future_status::timeout)
{
cout << "AsyncMethodThrowsException timed out";
}
else if (status == std::future_status::ready)
{
cout << "AsyncMethodThrowsException successfully completed";
try
{
if(executionFuture.valid())
{
executionFuture.get();
}
}
catch(const std::exception& ex)
{
cout << "AsyncMethodThrowsExceptionTest catch block";
}
}
}
void AsyncMethodThrowsException()
{
throw runtime_error("Exception from AsyncMethodThrowsException");
}
I have this:
catch (Except& e) {
std::cout << e.print() << std::endl;
}
I want this to print: OK you won!
so I have the class:
class Except{
public:
std::string print() {
std::string error("OK you won!\n");
return error;
}
};
I have this error in the Except class: "'string' in namespace 'std' does not name a type"
You have to include the header for std::string : #include <string>
You're probably not throwing it right - works for me:
#include <iostream>
#include <string>
class Except{
public:
std::string stack() {
std::string error("OK you won!\n");
return error;
}
};
int main() {
try {
throw Except();
} catch (Except& e) {
std::cout << e.stack() << std::endl;
}
return 0;
};
Output:
OK you won!
Check the code below:
#include <iostream>
#include <string>
class Except{
public:
std::string stack() {
std::string error("OK you won!\n");
return error;
}
};
int main() {
try {
throw Except();
} catch (Except &e) {
std::cout << e.stack() << std::endl;
}
return 0;
}
The output is:
./a.out
OK you won!
This is the code I have.
try
{
// code throws potentially unknown exception
}
catch (...)
{
std::exception_ptr eptr = std::current_exception();
// then what ?
}
Ideally, I would like to get the string associated to the exception if it is a std::exception.
// then what ?
here is what:
#include <exception>
#include <stdexcept>
#include <iostream>
#include <string>
std::string what(const std::exception_ptr &eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }
try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() ; }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}
int main()
{
try { throw std::runtime_error("it's success!"); }
catch (...) { std::cerr << "Here is WHAT happened: " << what() << std::endl; }
try { throw 42; } catch (...) { std::cerr << "and now what: " << what() << std::endl; }
}
what it prints:
Here is WHAT happened: it's success!
and now what: who knows
http://coliru.stacked-crooked.com/a/1851d2ab9faa3a24
so this allows to get what in the catch-all clause.
but what if exception is nested??? here is what:
std::string what(const std::exception_ptr &eptr = std::current_exception());
template <typename T>
std::string nested_what(const T &e)
{
try { std::rethrow_if_nested(e); }
catch (...) { return " (" + what(std::current_exception()) + ")"; }
return {};
}
std::string what(const std::exception_ptr &eptr)
{
if (!eptr) { throw std::bad_exception(); }
try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() + nested_what(e); }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}
using example from here:
#include <fstream>
...
// sample function that catches an exception and wraps it in a nested exception
void open_file(const std::string& s)
{
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch(...) {
std::throw_with_nested( std::runtime_error("Couldn't open " + s) );
}
}
// sample function that catches an exception and wraps it in a nested exception
void run()
{
try {
open_file("nonexistent.file");
} catch(...) {
std::throw_with_nested( std::runtime_error("run() failed") );
}
}
int main()
{
try { throw std::runtime_error("success!"); }
catch (...) { std::cerr << "Here is WHAT happened: \"" << what() << '\"' << std::endl; }
try { run(); }
catch (...) { std::cerr << "what happened for run: \"" << what() << '\"' << std::endl; }
}
what is printed:
Here is WHAT happened: "success!"
what happened for run: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"
http://coliru.stacked-crooked.com/a/901a0c19297f02b5
but what if recursion too deep? what if stackoverflow? optimized what:
#include <typeinfo>
template <typename T>
std::exception_ptr get_nested(const T &e)
{
try
{
auto &nested = dynamic_cast<const std::nested_exception&>(e);
return nested.nested_ptr();
}
catch (const std::bad_cast &)
{ return nullptr; }
}
#if 0 // alternative get_nested
std::exception_ptr get_nested()
{
try { throw ; }
catch (const std::nested_exception &e) { return e.nested_ptr(); }
catch (...) { return nullptr ; }
}
#endif
std::string what(std::exception_ptr eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }
std::string whaaat;
std::size_t num_nested = 0;
next:
{
try
{
std::exception_ptr yeptr;
std::swap(eptr, yeptr);
std::rethrow_exception(yeptr);
}
catch (const std::exception &e) { whaaat += e.what() ; eptr = get_nested(e); }
catch (const std::string &e) { whaaat += e ; }
catch (const char *e) { whaaat += e ; }
catch (...) { whaaat += "who knows"; }
if (eptr) { whaaat += " ("; num_nested++; goto next; }
}
whaaat += std::string(num_nested, ')');
return whaaat;
}
the same whats:
Here is WHAT happened: "success!"
here is what: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"
http://coliru.stacked-crooked.com/a/32ec5af5b1d43453
UPD
The similar functionality can be implemented in C++03 by using a trick that allows to rethrow current exception outside of catch block: https://stackoverflow.com/a/3641809/5447906
try
{
std::rethrow_exception(eptr);
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
http://en.cppreference.com/w/cpp/error/exception_ptr
Using std::current_exception seems a bit over the top in your case, since you don't seem to want to store or copy the std::exception_ptr for later processing (which is its only intent, it doesn't help with gaining additional information about an unknown exception in any way). If you just want to treat the case of a std::exception, what about the simple:
try
{
// code throws potentially unknown exception
}
catch (const std::exception &e)
{
std::cerr << e.what() << '\n'; // or whatever
}
catch (...)
{
// well ok, still unknown what to do now,
// but a std::exception_ptr doesn't help the situation either.
std::cerr << "unknown exception\n";
}
Not the best solution in my opinion but seems to work.
try
{
// code throws potentially unknown exception
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
catch (...)
{
std::exception_ptr eptr = std::current_exception();
// then what ?
LogUnknownException();
}
Thanks to ForEveR for the initial solution but I am not sure if I want to throw again within the catch block.
I know it doesn't make sense to actually handle an exception thrown in a different thread, but is there some way I can get notified that at least an exception occurred? E.g. something like
#include <QtConcurrentRun>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
// std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
int main()
{
try
{
QtConcurrent::run(MyFunction);
}
catch(...)
{
std::cout << "Exception caught!" << std::endl;
}
}
exits quietly, even though an exception occurred. This is sometimes very confusing when the exception comes from deep down in the call stack somewhere.
------------EDIT-------------
I tried to write a wrapper like UmNyobe suggested, but I must be doing something wrong with the function pointers?
#include <QtConcurrentRun>
#include <QFutureWatcher>
#include <QObject>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
// std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
template<typename TFirstParam, typename... TParams>
bool ExceptionWrapper(TFirstParam firstParam, TParams&& ...params)
{
// Here 'firstParam' should be a function pointer, and 'params' are the arguments
// that should be passed to the function
try
{
firstParam(params...);
}
catch(...)
{
std::cout << "Exception caught!" << std::endl;
return false; // failure
}
return true; // success
}
struct MyClass : public QObject
{
Q_OBJECT
MyClass()
{
connect(&this->FutureWatcher, SIGNAL(finished()), this, SLOT(slot_finished()));
}
void DoSomething()
{
void (*myFunctionPointer)() = MyFunction;
bool (*functionPointer)(decltype(myFunctionPointer)) = ExceptionWrapper;
QFuture<bool> future = QtConcurrent::run(functionPointer);
this->FutureWatcher.setFuture(future);
}
QFutureWatcher<void> FutureWatcher;
void slot_finished()
{
std::cout << "Finished" << std::endl;
if(!this->FutureWatcher.result())
{
std::cout << "There was an error!" << std::endl;
}
}
};
#include "ExceptionWrapper.moc"
int main()
{
MyClass myClass = new MyClass;
myClass->DoSomething();
}
The error I get is on this line:
QFuture<bool> future = QtConcurrent::run(functionPointer);
error: no matching function for call to 'run(bool (*&)(void (*)()))'
I know it doesn't make sense to actually handle an exception thrown in a different thread, but is there some way I can get notified that at least an exception occurred?
You can handle it by using the future returned from QtConcurrent::run. See this page for details. When you collect on the future, any unhandled exceptions will be rethrown. You can make a simple wrapper class to capture an exception and examine it in the receiving thread.
#include <QtGui>
#include <iostream>
#include <stdexcept>
class MyException : public QtConcurrent::Exception
{
public:
MyException(std::exception& err) : e(err) {}
void raise() const { throw *this; }
Exception* clone() const { return new MyException(*this); }
std::exception error() const { return e; }
private:
std::exception e;
};
// first concurrent function
int addFive(int n)
{
try
{
throw std::runtime_error("kablammo!");
//throw -1;
return n + 5;
}
catch (std::exception& e)
{
throw MyException(e);
}
}
// second concurrent function
void myVoidFunction()
{
try
{
throw std::runtime_error("oops!");
//throw -1;
}
catch (std::exception& e)
{
throw MyException(e);
}
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFuture<int> f1 = QtConcurrent::run(addFive, 50);
try
{
int r = f1.result();
std::cout << "result = " << r << std::endl;
}
catch (MyException& me)
{
std::cout << me.error().what() << std::endl;
}
catch (QtConcurrent::UnhandledException&)
{
std::cout << "unhandled exception in addFive\n";
}
QFuture<void> f2 = QtConcurrent::run(myVoidFunction);
try
{
// result() not available for QFuture<void>, use waitForFinished() to
// block until it's done.
f2.waitForFinished();
std::cout << "myVoidFunction finished\n";
}
catch (MyException& me)
{
std::cout << me.error().what() << std::endl;
}
catch (QtConcurrent::UnhandledException&)
{
std::cout << "unhandled exception in myVoidFunction\n";
}
QWidget w;
w.show();
return app.exec();
}
It seems that if an exception is thrown, the isCanceled() of an associated QFutureWatcher returns true:
#include <QApplication>
#include <QtConcurrentRun>
#include <QFutureWatcher>
#include <iostream>
#include <stdexcept>
void MyFunction()
{
std::cout << "MyFunction()" << std::endl;
throw std::runtime_error("Test exception.");
}
struct MyClass : public QObject
{
Q_OBJECT
public:
MyClass()
{
connect(&this->FutureWatcher, SIGNAL(finished()), this, SLOT(slot_finished()));
}
void DoSomething()
{
QFuture<void> future = QtConcurrent::run(MyFunction);
this->FutureWatcher.setFuture(future);
}
QFutureWatcher<void> FutureWatcher;
public slots:
void slot_finished()
{
std::cout << "Finished" << std::endl;
if(this->FutureWatcher.isCanceled())
{
std::cout << "There was an error!" << std::endl;
}
else
{
std::cout << "Success!" << std::endl;
}
}
};
#include "Exception.moc"
int main(int argc, char*argv[])
{
MyClass myClass;
myClass.DoSomething();
QApplication app(argc, argv);
return app.exec();
}
--------- Edit (Simplified version of Gordon Freeman's answer) ---------
The exceptions seem to be re-thrown even without using a QtConcurrent::Exception subclass?
#include <QtGui>
#include <iostream>
#include <stdexcept>
// non-void concurrent function
int addFive(int n)
{
throw std::runtime_error("addFive throw!");
return n+5;
}
// void concurrent function
void myVoidFunction()
{
throw std::runtime_error("myVoidFunction throw!");
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFuture<int> f1 = QtConcurrent::run(addFive, 50);
try
{
int r = f1.result();
std::cout << "result = " << r << std::endl;
}
catch (...)
{
std::cout << "exception in addFive." << std::endl;
}
QFuture<void> f2 = QtConcurrent::run(myVoidFunction);
try
{
// result() not available for QFuture<void>, use waitForFinished() to
// block until it's done.
f2.waitForFinished();
std::cout << "myVoidFunction finished\n";
}
catch (...)
{
std::cout << "exception in myVoidFunction\n";
}
QWidget w;
w.show();
return app.exec();
}
The good thing about QtConcurrent::run is that it accepts functions with a return value.
My two cents : catch the exception as early as possible...
disclaimer : I am really bad with exceptions in c++ :D
The code which is called in a different thread should return a value. In the case of a void function, or an existing function which doesn't catch exception you can define a wrapper (generic or not). For instance
int exceptionwrapper(){
int exception = 0;
try
{
myFunction();
}
catch(...){
exception = 1;
std::cout << "Exception caught!" << std::endl;
}
return exception;
}
Then later
QFuture<int> future = QtConcurrent::run(exemptionwrapper);
futurewatcher.setFuture(future);
You just use the future watcher to be able to examine the future later, when the function is over.