Currently, I am investigating some code that uses the CFile class from the MFC Library to open a text file.
I found two kinds of error handling in the code: This are just sample since it is confidential to post the code.. Just think that the body of the try statement contains only member functions of CFile class.
1
try {
if(file.Open(strPath,Cfile::modeRead|CFile::shareDenyNone)){
file.Read(strKey, dataLength);
file.Close();
}
}
catch (CFileException& e) {
}
2
try {
// same code above
}
catch (CFileException *e) {
}
What is the difference between the two kinds of exception handling?
What are the possible errors that can be thrown by member functions of the CFile class?
Is no. 1 way possible for catching exceptions thrown by a member function of the CFile class?
You can throw exception objects in two ways, by value:
CException ex;
throw ex; // CException
or by pointer:
CException *ex = new CException();
throw ex; // CException *
When catching the exception, you catch the corresponding type of what has been thrown, that is, a pointer, or a value. To avoid a copy, we usually catch-by-value using a reference:
catch(CException &e) // when throwing CException
MFC throws exceptions by pointer; see https://msdn.microsoft.com/en-us/library/0e5twxsh.aspx
try {
AfxThrowUserException();
}
catch( CException* e ) {
e->Delete();
}
Don't forget do delete the exception afterwards, or you get a small memory leak each time an exception is thrown.
Related
In C++ reference regarding the set_exception method , the example uses std::current_exception. To do that you have to throw and catch your exception:
std::thread t([&p]{
try {
// code that may throw
throw std::runtime_error("Example");
} catch(...) {
try {
// store anything thrown in the promise
p.set_exception(std::current_exception());
// or throw a custom exception instead
// p.set_exception(std::make_exception_ptr(MyException("mine")));
} catch(...) {} // set_exception() may throw too
}
});
This throwing and catching is obviously tedious, but the method accepts a std::exception_ptr. I was wondering whether it's possible to set a specific exception directly. I imagine the problem would be that a local exception object would have lifetime issues if we pass around a pointer to its address and allocating a new exception object would leave memory leaks. Is there a way ?
I have a try-catch block like below
try
{
// Do something here.
}
catch (const std::exception &e)
{
// std exception.
}
catch(...)
{
// Unknown exception. We can't know the type.
}
I am reading some documentation from http://www.cplusplus.com/reference/exception/exception/ but to me it is not obvious how to know what exception type was caught when the code goes into the std::exception part.
Is there a way to get a string with the type of error? (I don't want to surface the error message, just the exception type)
Is there a way to get a string with the type of error?
Sort of. If you catch by reference (as you are doing in the above code), then you can apply typeid to the exception to get some info about its dynamic type. This is made possible by the fact that std::exception is a polymorphic type. However, there's no guarantee that std::type_info::name() is a readable name for the type.
You can catch different exceptions with different catch blocks:
try
{
// Do something here.
}
catch (const std::runtime_error& e)
{
// Handle runtime error
}
catch (const std::out_of_range& e)
{
// Handle out of range
}
catch (const std::exception &e)
{
// Handle all other exceptions
}
catch(...)
{
// Unknown exception. We can't know the type.
}
Of course it does not always make sense to have a seperate catch for every type of exception, so you still would need a way to tell what is the type of the exception within the catch(std::exception&) block, for which I refer you to this answer.
I know that in C++ you can catch an exception of any data type using:
try {
// throw exception here
} catch (...) {
// handle exception here
}
But I want to catch any C++ standard exception, such as std::logic_error, std::out_of_range, and not ones of other data types such as string or int. How can I catch only the C++ standard exceptions only? I want to call exp.what() on the passed in C++ standard exception object, and that's not possible using the above code.
All standard exceptions derive from std::exception, so catch that instead:
try {
// throw exception here
}
catch (const std::exception &e) {
// handle exception here
}
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();
}
I've the following piece of code
try
{
// Vector creation in shared memory. The shm must exist.
m_pxShm = new managed_shared_memory(open_only, pcShmName);
m_pxShm->construct<T>(pcVecName)[iSize](); // THROW EXCEPTION <==
m_xVectorPair = m_pxShm->find<T>(pcVecName);
if (0 == m_xVectorPair.first)
{
throw std::exception();
}
}
catch (std::exception)
{
throw SharedMemoryVectorBadAllocException();
}
The SharedMemoryVectorBadAllocException use std::exception as base class. When I run this piece of code, the line with the 'construct' method throws an exception (because I create a vector bigger than shared memory). But the thrown exception is not handled, and the application crashes. Even if I debug it, line by line, the exception is not handled by the catch statement. I've tried to use as catch argument std::exception, interprocess_exception, ... and so on, without success. How can I handle the exception ? I'm using Visual studio 2010.