What's the need for special exception classes? - c++

Why did the C++ standard bother inventing the std::exception classes? What's their benefit? My reason for asking is this:
try
{
throw std::string("boom");
}
catch (std::string str)
{
std::cout << str << std::endl;
}
Works fine. Later, if I need, I can just make my own lightweight "exception" types. So why should I bother with std::exception?

Why did the C++ standard bother inventing the std::exception classes? What's their benefit?
It provides a generic and consistent interface to handle exceptions thrown by the standard library. All the exceptions generated by the standard library are inherited from std::exception.
Note that standard library api's can throw a number of different kinds of exceptions, To quote a few examples:
std::bad_alloc
std::bad_cast
std::bad_exception
std::bad_typeid
std::logic_error
std::runtime_error
std::bad_weak_ptr | C++11
std::bad_function_call | C++11
std::ios_base::failure | C++11
std::bad_variant_access | C++17
and so on...
std::exception is the base class for all these exceptions:
providing a base class for all these exceptions, allows you to handle multiple exceptions with a common exception handler.
If I need, I can just make my own lightweight "exception" types. So why should I bother with std::exception?
If you need your custom exception class go ahead and make one. But std::exception makes your job easier because it already provides a lot of functionality which a good exception class should have. It provides you the ease of deriving from it and overidding necessary functions(in particular std::exception::what()) for your class functionality.
This gives you 2 advantages the std::exception handler,
can catch standard library exceptions as well as
exceptions of the type of your custom exception class
Image courtesy: http://en.cppreference.com/w/cpp/error/exception

Why did the C++ standard bother inventing the std::exception classes? What's their benefit?
Having different kinds of exceptions allows you to catch specific types of errors. Deriving exceptions from a common base allows for granularity in catching more generic or specific errors depending on circumstance.
In C++ an existing type system is already in place, so standardizing error strings was unnecessary when you can explicitly create an exception of a desired type in the language.
std::exception and its derived classes exist for two main reasons:
The standard library has to have some kind of exception hierarchy to
throw in exceptional circumstances. It would be inappropriate to
always throw an std::string because you would have no clean way to
target specific kinds of errors.
To provide an extensible class based interface for library vendors to throw the most basic error types and provide a common fallback for users. You may want to provide more error metadata than a simple what() string so that the person catching your error can more intelligently recover from it.
At the same time std::exception as a common base allows a general catchall less all-encompassing than ... if the user only cares about that error message.
If all you ever do is print and quit then it doesn't really matter, but you may as well use std::runtime_error which inherits from std::exception for catch convenience.
Later, if I need, I can just make my own lightweight "exception" types. So why should I bother with std::exception?
If you inherit from std::runtime_error and use your own custom error type then you can retroactively add error metadata without having to rewrite catch blocks! In contrast, if you ever changed your error handling design then you would be forced to rewrite all your std::string catches because you cannot safely inherit from std::string. It is not a forward-looking design decision.
If that doesn't seem so bad right now, imagine if your code were to become shared across multiple projects as a shared library with various programmers working on it. Migrating to the new version of your library would become a pain.
This isn't even mentioning that std::string can throw its own exceptions during copy, construction, or access of characters!
Boost's website has some good guidelines in exception handling and class construction here.
User Story
I am writing some network code and using a third party vendor's
library. On an invalid ip address being entered by the user this
library throws a custom exception nw::invalid_ip derived from
std::runtime_error. nw::invalid_ip contains a what() describing
the error message, but also the incorrect_ip() address supplied.
I also use std::vector to store sockets, and am making use of the
checked at() call to safely access indices. I know that if I
call at() on a value out of bounds std::out_of_range is thrown.
I know other things may be thrown as well, but I do not know how to
handle them, or what exactly they might be.
When I get an nw::invalid_ip error I pop up a modal with an input
box for the user populated with the invalid ip address so they can edit
it and try again.
For std::out_of_range issues, I respond by running an integrity check
on the sockets and fixing the vector/socket relationship that has fallen
out of synch.
For any other std::exception issues I terminate the program with an
error log. Finally I have a catch(...) which logs "unknown error!" and
terminates.
It would be difficult to robustly do this with only std::string being thrown.
Here's a basic example of a few things being thrown in different cases so you can play with catching exceptions.
ExampleExceptions.cpp
#include <vector>
#include <iostream>
#include <functional>
#include <stdexcept>
#include <bitset>
#include <string>
struct Base1 {
virtual ~Base1(){}
};
struct Base2 {
virtual ~Base2(){}
};
class Class1 : public Base1 {};
class Class2 : public Base2 {};
class CustomException : public std::runtime_error {
public:
explicit CustomException(const std::string& what_arg, int errorCode):
std::runtime_error(what_arg),
errorCode(errorCode){
}
int whatErrorCode() const {
return errorCode;
}
private:
int errorCode;
};
void tryWrap(typename std::function<void()> f){
try {
f();
} catch(CustomException &e) {
std::cout << "Custom Exception: " << e.what() << " Error Code: " << e.whatErrorCode() << std::endl;
} catch(std::out_of_range &e) {
std::cout << "Range exception: " << e.what() << std::endl;
} catch(std::bad_cast &e) {
std::cout << "Cast exception: " << e.what() << std::endl;
} catch(std::exception &e) {
std::cout << "General exception: " << e.what() << std::endl;
} catch(...) {
std::cout << "What just happened?" << std::endl;
}
}
int main(){
Class1 a;
Class2 b;
std::vector<Class2> values;
tryWrap([](){
throw CustomException("My exception with an additional error code!", 42);
});
tryWrap([&](){
values.at(10);
});
tryWrap([&](){
Class2 c = dynamic_cast<Class2&>(a);
});
tryWrap([&](){
values.push_back(dynamic_cast<Class2&>(a));
values.at(1);
});
tryWrap([](){
std::bitset<5> mybitset (std::string("01234"));
});
tryWrap([](){
throw 5;
});
}
Output:
Custom Exception: My exception with an additional error code! Error Code: 42
Range exception: vector::_M_range_check
Cast exception: std::bad_cast
Cast exception: std::bad_cast
General exception: bitset::_M_copy_from_ptr
What just happened?

It's a legitimate question because std::exception only really contains a single property: what(), a string. So it's tempting to just use string instead of exception. But the fact is that an exception is not a string. If you treat an exception like it's merely a string, you lose the ability to derive from it in specialized exception classes that would provide more properties.
For example today you throw strings in your own code. Tomorrow you decide to add more properties to certain cases like a database connection exception. You can't just derive from string to make this change; you will need to write a new exception class and change all the exception handlers for string. Using exception is a way for exception handlers to use only the data they care about, to pick and choose exceptions as they need to handle them.
Also if you throw and handle only string-typed exceptions, you will miss all exceptions thrown from any code that's not your own. If this distinction is intentional, it would be best described by using a common exception class to signify this, not the generic type of string.
exception is also more specific than string. This means library developers can write functions that accept exceptions as parameters, which is clearer than accepting a string.
All of this is essentially free, just use exception instead of string.

Just because something "works fine" in a 6 line toy example doesn't mean it is scalable or maintainable in real code.
Consider this function:
template<typename T>
std::string convert(const T& t)
{
return boost:lexical_cast<std::string>(t);
}
This could throw bad_alloc if memory for the string cannot be allocated, or could throw bad_cast if the conversion fails.
A caller of this function might want to handle the failed conversion case which indicates bad input but isn't a fatal error, but not want to handle the out-of-memory case, because they can't do anything about it so let the exception propagate up the stack. This is very easy to do in C++, for example:
std::string s;
try {
s = convert(val);
} catch (const std::bad_cast& e) {
s = "failed";
}
If exceptions were just thrown as std::string the code would have to be:
std::string s;
try {
s = convert(val);
} catch (const std::string& e) {
if (e.find("bad_cast") != std::string::npos)
s = "failed";
else
throw;
}
This takes more code to implement and relies on the exact wording of the exception string, which might depend on the compiler implementation and the definition of boost::lexical_cast. If every piece of exception handling in the system had to do string comparisons to decide if the error can be handled at that point it would be messy and unmaintainable. A small change to the spelling of an exception message in one part of the system that throws exceptions might cause the exception handling code in another part of the system to stop working. This creates tight coupling between the location of an error and every bit of error handling code in the system. One of the advantages of using exceptions is to allow error handling to be separated from the main logic, you lose that advantage if you create dependencies based on string comparisons across the whole system.
Exception handling in C++ catches things by matching on the exception's type, it doesn't catch by matching on an exception's value, so it makes sense to throw things of different types to allow fine-grained handling. Throwing things of a single string type and handling them based on the string's value is messy, non-portable and more difficult.
Later, if I need, I can just make my own lightweight "exception" types. So why should I bother with std::exception?
If your code is useful and reusable and I want to use it in part of my system, do I have to add exception handling that catches all your lightweight types? Why should the whole of my system care about the internal details of a library that one bit of the system relies on? If your custom exception types are derived from std::exception then I can catch them by const std::exception& without knowing (or caring) about the specific types.

If you are the only user of the class,you can avoid std::exception(if you want to avoid the standard library exceptions)
But if your class is going to be used by others (programmers),how would they handle the exception.
If your class throws a string that describes the error,that would not help since the consumers of your class would prefer a more standard way(catch an exception object and query it's what method) to handle the exception rather than catching a string..
Also you can catch exceptions thrown by the standard library by catching an exception object
You can override the what method of exception class to give more information about the error.

Wow, I'm surprised no one mentioned this:
You need multiple types of exceptions in order to be able to distinguish them -- some kinds of exceptions should be handled, while others shouldn't.
They need to have a common base class to allow you to have a means for displaying a sane message to the user without having to know all the types of exceptions that your program could possibly throw (which is impossible when using external closed source libraries).

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

What should I pass to throw?

I added a bunch of exceptions to my hash table class to deal with various issues that might come up. They are mostly constructed like this:
std::string msg = std::string("I made doodoo, some value: ") + std::tostring(value);
throw std::exception(msg.c_str());
Some of the exceptions are part of normal operation, for example there is one that says the table is full and the thing that catches it then rebuilds the table into a bigger one. I discovered that this puts a sizable dent in the performance though, I suspect its all the string construction. At the same time though, I want the exceptions to be meaningful and make sense to somebody who doesn't know what the code numbers I come up with mean. Whats a good way to deal with this?
Ideally you should be creating custom exception classes from std::exception. That way when you create your catch blocks, you can have a specific catch for each of your exceptions. Example:
class MyException; // Inherits from std::exception.
class MyOtherException; // Inherits from std::exception.
void foo()
{
if (bar)
throw MyException();
if (baz)
throw MyOtherException();
// do stuff.
}
int main()
{
try
{
foo();
}
catch(const MyException &ex)
{
// Handle MyException.
}
catch (const MyOtherException &ex)
{
// Handle MyOtherException.
}
}
Creating your own exception classes affords you a lot more flexibility because it allows you to attach additional information to your exceptions, as well as handling different exception types as described above.
class MyException : public std::exception
{
private:
std::string m_description;
int m_userId;
public:
MyException(const std::string &errorDescription = "Unhandled exception", const int userId) :
m_description(errorDescription),
m_userId(userId)
{
}
int get_user_id() const
{
return m_userId;
}
virtual const char *what() const
{
return m_description.c_str();
}
}
The main problem with your code (at least how you described it) however is that you seem to be controlling your program flow with exceptions. Exceptions are not designed to be fast constructs, they're designed for exceptional cases that would, if not handled, cause your program to crash. Attempting to use exceptions in place of if statements is going to make your code very slow, very hard to read, and even harder to understand/maintain.
To take from your example: if you're adding to a hash table, and need to resize the table, why do you need to throw an exception, when you could just resize it? This is exactly how an std::vector works. If you do a push_back() on a vector and vector.capacity() < vector.size() + 1, the vector will internally re-allocate the buffer so that the new item can be added. The only time an exception might be thrown is if you run out of memory. The caller isn't aware of any of this, it just calls vector.push_back(...).

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.

usage of exception in c++

In my project codding i have to use a try catch method to find the function execution status.
try
{
//sample code
//calling functions
function1();
function2();
//........
}
catch(//need to catch exception)
{
return failure;
}
My requirement is that i have to catch all the exceptions that thrown from the try block
i have two options here,
catch(...)
catch(std::exception)
I think the first one will catch all the exceptions. And the second one, std::exception is the base class for all other exception classes in my program
class MyException : public std::exception
{
// All the exceptions that i have use is derived from this class
}.
Which is better and more efficient.
Is the both method works same way. Help me and suggest any method
In this case, you'd work your way through the types which may be thrown in the following order:
catch (MyException& e) {
...
}
catch (std::exception& e) {
...
}
catch (...) {
...
}
This way, you can handle the specific errors/types first, and then fall back on the weak (or untyped) handlers when the preceding handlers do not match.
Which is better and more efficient.
The order I recommended is best for handling by type. IMO, efficiency is not a concern in this scenario because correctness takes precedence and hopefully exceptions are thrown only under exceptional circumstances.
Always keep your specification as focused as possible so that you catch those that you know could be thrown, and catch derived exceptions (more specialised) before base ones:
try
{
// Some stuff
}
catch (Derived& e)
{
// Deal with specifics of Derived
}
catch (Base& e)
{
// Deal with general case of Base
}
Never use catch(...) except at the very top of your program stack (and certainly not in libraries.) When you do this, you cannot be sure about what caused the exception and therefore you cannot necessarily rely on things that you normaly would (such as memory management etc.)
I would suggest you to catch the specified exceptions only and use the catch(...) only in the main function. In my opinion the better way to use the exceptions is to implement one exception per module so each class will throw the specific exception related with the module of the class also different exceptions may be handled with a different way so I believe that
catch(const ExceptionType1& e){
}catch(const ExceptionType2& e){
}
is the better solution, also some other developer just reading this code will see which kind of exceptions could be thrown and handled....

How can I catch all types of exceptions in one catch block?

In C++, I'm trying to catch all types of exceptions in one catch (like catch(Exception) in C#). How is it done? And what's more, how can one catch divide-by-zero exceptions?
catch (...)
{
// Handle exceptions not covered.
}
Important considerations:
A better approach is to catch specific types of exception that you can actually recover from as opposed to all possible exceptions.
catch(...) will also catch certain serious system level exceptions (varies depending on compiler) that you are not going to be able to recover reliably from. Catching them in this way and then swallowing them and continuing could cause further serious problems in your program.
Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown. In this case, you log all useful local state information and then re-throw the exception to allow it to propagate up. However you should read up on the RAII pattern if you choose this route.
You don't want to be using catch (...) (i.e. catch with the ellipsis) unless you really, definitely, most provable have a need for it.
The reason for this is that some compilers (Visual C++ 6 to name the most common) also turn errors like segmentation faults and other really bad conditions into exceptions that you can gladly handle using catch (...). This is very bad, because you don't see the crashes anymore.
And technically, yes, you can also catch division by zero (you'll have to "StackOverflow" for that), but you really should be avoiding making such divisions in the first place.
Instead, do the following:
If you actually know what kind of exception(s) to expect, catch those types and no more, and
If you need to throw exceptions yourself, and need to catch all the exceptions you will throw, make these exceptions derive from std::exception (as Adam Pierce suggested) and catch that.
If you are on windows and need to handle errors like divide by zero and access violation you can use a structured exception translator. And then inside of your translator you can throw a c++ exception:
void myTranslator(unsigned code, EXCEPTION_POINTERS*)
{
throw std::exception(<appropriate string here>);
}
_set_se_translator(myTranslator);
Note, the code will tell you what the error was. Also you need to compile with the /EHa option (C/C++ -> Code Generatrion -> Enable C/C++ Exceptions = Yes with SEH Exceptions).
If that doesn't make sense checkout the docs for [_set_se_translator](http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)
If catching all exceptions - including OS ones - is really what you need, you need to take a look at your compiler and OS. For example, on Windows you probably have "__try" keyword or compiler switch to make "try/catch" catch SEH exceptions, or both.
Make all your custom exception classes inherit from std::exception, then you can simply catch std::exception. Here is some example code:
class WidgetError
: public std::exception
{
public:
WidgetError()
{ }
virtual ~WidgetError() throw()
{ }
virtual const char *what() const throw()
{
return "You got you a widget error!";
}
};
In C++, the standard does not define a divide-by-zero exception, and implementations tend to not throw them.
You can, of course, use catch (...) { /* code here */ }, but it really Depends On What You Want To Do. In C++ you have deterministic destructors (none of that finalisation rubbish), so if you want to mop up, the correct thing to do is to use RAII.
For example. instead of:
void myfunc()
{
void* h = get_handle_that_must_be_released();
try { random_func(h); }
catch (...) { release_object(h); throw; }
release_object(h);
}
Do something like:
#include<boost/shared_ptr.hpp>
void my_func()
{
boost::shared_ptr<void> h(get_handle_that_must_be_released(), release_object);
random_func(h.get());
}
Create your own class with a destructor if you don't use boost.
You can use catch(...) to catch EVERYTHING, but then you don't get a an object to inspect, rethrow, log, or do anything with exactly. So... you can "double up" the try block and rethrow into one outer catch that handles a single type. This works ideally if you define constructors for a custom exception type that can build itself from all the kinds you want to group together. You can then throw a default constructed one from the catch(...), which might have a message or code in it like "UNKNOWN", or however you want to track such things.
Example:
try
{
try
{
// do something that can produce various exception types
}
catch( const CustomExceptionA &e ){ throw e; } \
catch( const CustomExceptionB &e ){ throw CustomExceptionA( e ); } \
catch( const std::exception &e ) { throw CustomExceptionA( e ); } \
catch( ... ) { throw CustomExceptionA(); } \
}
catch( const CustomExceptionA &e )
{
// Handle any exception as CustomExceptionA
}
If I recall correctly (it's been a while since I've looked at C++), I think the following should do the trick
try
{
// some code
}
catch(...)
{
// catch anything
}
and a quick google(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html) seems to prove me correct.