This question already has answers here:
C++ get description of an exception caught in catch(...) block
(6 answers)
Closed 6 years ago.
If I want to write useful info to a file whenever i caught a catch-all exception, how to do it?
try
{
//call dll from other company
}
catch(...)
{
//how to write info to file here???????
}
You can't get any information out of the ... catch block. That is why code usually handles exceptions like this:
try
{
// do stuff that may throw or fail
}
catch(const std::runtime_error& re)
{
// speciffic handling for runtime_error
std::cerr << "Runtime error: " << re.what() << std::endl;
}
catch(const std::exception& ex)
{
// speciffic handling for all exceptions extending std::exception, except
// std::runtime_error which is handled explicitly
std::cerr << "Error occurred: " << ex.what() << std::endl;
}
catch(...)
{
// catch any other errors (that we have no information about)
std::cerr << "Unknown failure occurred. Possible memory corruption" << std::endl;
}
A caught exception is accessible by the function std::current_exception(), which is defined in <exception>. This was introduced in C++11.
std::exception_ptr current_exception();
However, std::exception_ptr is an implementation-defined type, so you can't get to the details anyway. typeid(current_exception()).name() tells you exception_ptr, not the contained exception. So about the only thing you can do with it is std::rethrow_exception(). (This functions seems to be there to standardize catch-pass-and-rethrow across threads.)
There's no way to know anything about the specific exception in a catch-all handler. It's best if you can catch on a base class exception, such as std::exception, if at all possible.
You can't get any details. The whole point of catch(...) is to have such "I don't know what can happen, so catch whatever is thrown". You usually place catch(...) after catch'es for known exception types.
I think he wants to make it log that an error occurred, but doesn't specifically need the exact error (he would write his own error text in that case).
The link DumbCoder posted above has at tutorial that will help you get what you're trying to achieve.
Related
Gtk::Builder::create_from_resource() throws the following exceptions when something goes wrong, for instance, the resource file wasn't found or there's a markup error in the Glade/UI file, etc
BuilderError
Glib::MarkupError
Gio::ResourceError
But I don't have any intention to handle those exceptions and do something else in my GTKMM program.
In case, if I have to implement try/catch block out of good programming practice, bare basic code would look like this:
try {
auto resource = Gtk::Builder::create_from_resource("/domain/reverse/myappid");
} catch (const Gio::ResourceError &ex) {
cerr << ex.what();
} catch (const Glib::MarkupError &ex) {
cerr << ex.what();
} catch (const Gtk::BuilderError &ex) {
cerr << ex.what();
}
I'm just printing the same exception message if any one of them was thrown... But anyway even without implementing the try/catch block, I still get the same meaningful message. And in both cases, the program would run just fine, no application crashes intended. Just the info printed on console for developers.
So is it safe to write less and readable code without the try/catch block for Gtk::Builder::create_from_resource?
If you really don't want to handle the exception, the program will simply terminate abruptly if some exception is thrown.
I personally prefer to use global exception handling in these cases. In your case, all exceptions derive from std::exception or Gtk::BuilderError, so your handler could look like:
int main()
{
try
{
// Program code, eventually a call to `Gtk::Builder::create_from_resource`.
}
catch(const std::exception& p_exception)
{
cerr << p_exception.what();
}
catch(const Gtk::BuilderError& p_exception)
{
cerr << p_exception.what();
}
return 0;
}
What I like about this is that I don't have to put try-catch blocks everywhere for exceptions I have no intention of handling (ex.: the user somehow revoved the ressource file), but I can log something for debug purposes, or warn the user instead of simply crashing (i.e terminating).
You could also use the catch-all syntax:
int main()
{
try
{
// Program code, eventually a call to `Gtk::Builder::create_from_resource`.
}
catch(...)
{
// Do something, but the exception message is not available.
}
return 0;
}
This has the advantage of catching everything (even exceptions that are not child classes of std::exception), but has the disadvantage that you loose the exception message, as least for standard C++.
Suppose I have two inheritance hierarchies I'm dealing with in C++. One inherits from std::exception (new hierarchy), and the other inherits from Exception (legacy C++ Builder VCL base exception class). If I call code that may throw either type of exception, I have to write code like this:
try {
// do stuff....
Function1();
Function2();
} catch (std::exception &ex) {
std::cout << "STL exception caught: " << ex.what() << std::endl;
} catch (Exception &ex) {
std::cout << "Legacy exception caught: " << ex.Message.c_str() << std::endl;
} catch (SomeOtherVendorLibraryException &ex) {
// etc.
}
The problem is that each caller needs to have all these catch clauses to try to get every last type of exception, since C++ has no one true, enforced exception base class you can use as a catch-all (e.g. System.Exception class in C#). (catch (...) is a non-starter since you don't have a way of knowing what you caught, and some dangerous system exceptions, like access violations, could be caught as well which are better left untrapped.)
I would like to wrap these "legacy" exceptions into a class in the std::exception hierarchy. This concept of wrapping 3rd-party exceptions into your own exception system isn't entirely unprecedented. For example, the .NET Framework wraps broad sets of errors in other systems (e.g. COMException). Ideally, I'd like to see something like this:
class LegacyException : public std::runtime_error {
public:
// construct STL exception from legacy exception
LegacyException(const Exception &ex) : std::runtime_error(ex.Message.c_str()) {}
};
try {
// In reality, this throw will happen in some function we have no control over.
throw Exception("Throwing legacy exception!");
} catch (std::exception &ex) {
// Ideally, the compiler would use the LegacyException constructor
// to cast the thrown Exception to a LegacyException, which ultimately
// inherits from std::exception.
std::cout << ex.what() << std::endl;
}
Understandably, the exception is never caught - it would be asking quite a bit of magic from the compiler for it to catch it.
Is there a solution that might be similar to the above for wrapping a legacy exception, and achieves these goals?
One "catch" clause or similar, so that general exception handling logic need only be written once.
Logic for converting from one exception type to another must be centralized.
Avoids macros if possible.
No use of lambda functions.
Having worked with BC++Builder I have met the same problem, and macros seemed to be the only solution at the time.
The "cleaner" (hum...) solution is probably a "double-try-catch": the inner try-catch converts your legacy exception into a standard class, and the outer one actually handles the exception.
I don't have the code at hand (it's been years) but basically it boils down to:
#define DTRY try { try
#define DCATCH catch (Exception& e) { throw LegacyException(e); } } catch
DTRY {
...
}
DCATCH(std::exception& e) {
// handle the exception
}
Yes I know it's ugly, but when I worked with Borland I didn't find anything better. Fact is, at that time Borland was awfully non-standard and I have no idea how it evolved since, maybe you can do better nowadays. Hope this helps anyway.
I am calling a function and I am throwing an exception in that function. But I don't want to catch that in the same function but want to catch it where that function was called, like here is my example code.
void foo()throw(...){
std::cout << "FOO" <<std::endl;
throw "Found";
}
void main(){
try{
foo();
}
catch(...){
std::cout << "exception catched" <<std::endl;
}
}
But it is crashing at the point where I am throwing the exception in foo function, but I want to catch it in the main function.
How would I do that?
throw;
throw with no operand rethrows the exception that is currently being handled. That means it can only be used in a catch block. Since you aren't in a catch block when the throw; is executed, the program is terminated.
You need to throw something, like a runtime error: throw std::runtime_error("oops");.
Note also that exception specifications (e.g. the throw(...) in void foo() throw(...)) should not be used. For an explanation as to why, see "A Pragmatic Look at Exception Specifications."
Got answer my own question at http://msdn.microsoft.com/en-US/library/wfa0edys%28v=VS.80%29.aspx
Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?
try
{
//some operation
}
catch(...)
{
}
No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.
You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).
If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.
The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.
Addition: look at this article at "The Old New Thing" for some insights.
It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.
While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.
It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.
It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.
You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Determining exception type after the exception is caught?
Following up on this question , I'd like to print out the current exception in a catch(...) block -- just for logging. One answer there says that there is no standard way of doing this, but I don't like taking no for an answer :-)
current_exception() is a function mentioned in various places on the web but apparently not well-supported. Any thoughts on this? After all, even C has errno.
Because it can be rethrown (with a simple **throw*), the exception object must be available somehow.
I am using MSVS 9.0.
Edit: The conclusion seems to be that this is not possible.
If you only care about exceptions that you know about when you're writing the code then you can write a handler that can deal with all 'known' exceptions. The trick is to rethrow the exception that you caught with catch(...) and then catch the various known exceptions...
So, something like:
try
{
...
}
catch(...)
{
if (!LogKnownException())
{
cerr << "unknown exception" << endl;
}
}
where LogKnownException() looks something like this:
bool LogKnownException()
{
try
{
throw;
}
catch (const CMyException1 &e)
{
cerr << "caught a CMyException: " << e << endl;
return true;
}
catch (const Blah &e)
{
...
}
... etc
return false;
}
Determine what exceptions can be thrown and use a set of catch handlers to catch a set of common base types that covers them all.
As for getting the exception object from catch(...), it can't be done portably and as far as I know, it can't be done at all using the Microsoft compiler or gcc. What makes you think the exception object still exists in a catch(...) handler anyway?
You can turn on RTTI and use typeOf function. current_exception is purely stl function, and applies to stl exceptions only.
As a recommendation, use different catch(exctype) per exception type. This will make life a lot easier.
Like alemjerus already said: current_exception works only for stl exceptions.
To get various stl errors you could also write:
#include <stdexcept>
#include <exception> //ecxeption (base class)
#include <new> //bad_alloc
#include <typeinfo> //bad_cast und bad_typeid
#include <ios> //ios_base::failure
...
try
{
...
}
catch(std::exception& e)
{
cerr<<"Error: "<<e.what()<<endl;
}