How can I determine the current exception in a catch (...) block? [duplicate] - c++

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;
}

Related

Catch(...) with unknown object - how do I identify what was thrown?

I have a library I use that throws something, but I don't know how to identify what was being thrown.
Sample code to reproduce this:
int main()
{
char* memoryOutOfBounds;
unsigned __int64 bigNumber = -1;
try {
throw std::string("Test");
memoryOutOfBounds = new char[bigNumber];
}
catch (const std::bad_alloc& ex)
{
printf("Exception: %s\n", ex.what());
}
catch (...)
{
printf("Unknown.\n");
}
return 0;
}
The new char[bigNumber] will throw a std::bad_alloc, which is derived from std::exception and will enter the first branch. The other one, throw std::string will enter the second branch. How can I check the object that was thrown? I tried with a catch(void*) in the hopes to catch any object in memory, but that did not happen, so how can I find out what was thrown and from there debug what may have caused this?
catch (...) {}
means: Catch absolute everything that was thrown and drop it. This is only meant as a safeguard, so no exceptions fly out of the window and bring down the whole house. (Aka: Application Termination by Unhandled Exception")
There is no way to tell what was thrown in here.
But as you actually know that an std::string can be thrown, you can catch it in a
catch (const std::string& s) {}
block. You do need to know what (type) was thrown whenever you want to catch exceptions.
However, most libraries which add their own types for exceptions will have them inherit from std::exception. Therefore a
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
block should get them.
If they do not inherit from std::exception and/or block the what() method, it is a stupid way to make the usage of their library extra difficult.
However, somewhere in the documentation of the library the exception throwing behaviour should be explained.
Edit : I think that Point 1. under "How should I design my exception classes" on the Boost Error Handling document is something every library developer should keep in mind. And hopefully the developers of your library did keep that principle in mind. ;-)
There really is no standard C++ way to query any information about the exception that is being thrown. Which is unfortunate, because the runtime has that information in order to match catch blocks. But there is just no access to that information in user code.
If it's purely for research purposes, like just finding out what the type is because the library you're using lacks documentation, you could use std::current_exception() to get a std::exception_ptr object that stores (or references) the thrown exception internally. This type is implementation-defined, but your debugger might happen to provide you with enough information.
#include <exception>
void foo()
{
try
{
function_that_throws();
}
catch(...)
{
std::exception_ptr p = std::current_exception();
// break here and inspect 'p' with a debugger
}
}
This stackoverflow post would be helpful-
C++ get description of an exception caught in catch(...) block
Since C++11 you can capture the current exception with a pointer:
std::exception_ptr p; // default initialization is to nullptr
try {
throw std::string("Test");
}
catch(...)
{
p = std::current_exception();
}

C++: How do I know what exception in catch with ellipsis [duplicate]

I know that you can catch "all exceptions" and print the exception by
try
{
//some code...
}catch(const std::exception& e) {
cout << e.what();
}
but this is just for exceptions derived from std::exception.
I was wondering if there is a way to get some information from an ellipsis catch
try
{
//some code...
}catch(...) {
// ??
}
If the mechanism is the same as ellipsis for functions then I should be able to do something like casting the argument of the va_list and trying to call the what() method.
I haven't tried it yet but if someone knows the way I'd be excited to know how.
From C++11 and onwards, you can use std::current_exception &c:
std::exception_ptr p;
try {
} catch(...) {
p = std::current_exception();
}
You can then "inspect" p by taking casts &c.
In earlier standards there is no portable way of inspecting the exception at a catch(...) site.
Sorry, you can't do that. You can only access the exception object in a catch block for a specific exception type.

Can you wrap one exception inheritance hierarchy into another? --or, another clean way to deal with this?

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.

C++ unhandled exceptions

Does C++ offer a way to 'show' something visual if an unhandled exception occurs?
What I want to do is to make something like assert(unhandled exception.msg()) if it actually happens (like in the following sample):
#include <stdexcept>
void foo() {
throw std::runtime_error("Message!");
}
int main() {
foo();
}
I expect this kind of code not to terminate immediately (because exception was unhandled), rather show custom assertion message (Message! actually).
Is that possible?
There's no way specified by the standard to actually display the message of the uncaught exception. However, on many platforms, it is possible anyway. On Windows, you can use SetUnhandledExceptionFilter and pull out the C++ exception information. With g++ (appropriate versions of anyway), the terminate handler can access the uncaught exception with code like:
void terminate_handler()
{
try { throw; }
catch(const std::exception& e) { log(e.what()); }
catch(...) {}
}
and indeed g++'s default terminate handler does something similar to this. You can set the terminate handler with set_terminate.
IN short, no there's no generic C++ way, but there are ways depending on your platform.
Microsoft Visual C++ allows you to hook unhandled C++ exceptions like this. This is standard STL behaviour.
You set a handler via a call to set_terminate. It's recommended that your handler do not very much work, and then terminate the program, but I don't see why you could not signal something via an assert - though you don't have access to the exception that caused the problem.
I think you would benefit from a catch-all statement as follows:
int main() {
try {
foo();
catch (...) {
// Do something with the unhandled exception.
}
}
If you are using Windows, a good library for handling unhandled exceptions and crashes is CrashRpt. If you want to do it manually you can also use the following I wrote in this answer.
If I'm reading your question correctly, you're asking if you can overload throw (changing its default behavior) so it does something user-defined. No, you can't.
Edit: since you're insistent :), here's a bad idea™:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
void monkey() {
throw std::exception("poop!");
}
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
std::cout << "poop was thrown!" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
monkey();
return 1;
}
Again, this is a very bad idea, and it's obviously platform-dependent, but it works.
Yes, its possible. Here you go:
#include <iostream>
#include <exception>
void foo()
{
throw std::exception("Message!");
}
int main()
{
try
{
foo();
}
catch (std::exception& e)
{
std::cout << "Got exception: " << e.what() << std::endl;
}
return 0;
}
The c++ standard is the terminate handler - as other have said
If you are after better traceablility for throws then this is what we do
We have a macro Throw that logs the file name and line number and message and then throws. It takes a printf style varargs message.
Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);
I get a nice log message
Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
If you're really interested in what happened to cause your program to fail, you might benefit from examining the process image in a post-mortem debugger. The precise technique varies a bit from OS to OS, but the basic train is to first enable core dumping, and compile your program with debug symbols on. Once the program crashes, the operating system will copy its memory to disk, and you can then examine the state of the program at the time it crashed.

how to get message of catch-all exception [duplicate]

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.