I have some special exception cases that I want to throw and catch, so I want to define my own exception classes.
What are the best practices for that? Should I inherit from std::exception or std::runtime_error?
Yes, it's good practice to inherit from std::runtime_error or the other standard exception classes like std::logic_error, std::invalid_argument and so on, depending on which kind of exception it is.
If all the exceptions inherit some way from std::exception it's easy to catch all common errors by a catch(const std::exception &e) {...}. If you have several independent hierarchies this gets more complicated. Deriving from the specialized exception classes makes these exceptions carry more information, but how useful this really is depends on how you do your exception handling.
I'm not a C++ developer, but one thing we did in our C# code was create a base class exception for our framework, and then log the exception thrown in the constructor:
public FrameworkException(string message, Exception innerException)
: base(message, innerException)
{
log.Error(message, innerException);
}
...
Any derived exception just has to invoke it's base constructor and we get consistent exception logging throughout. Not a big deal, but useful.
It is a good when exception is placed in some scope. For instance class Manipulation can declare inside exception classes Error.
and catch them like
catch ( const Manipulation::InputError& error )
catch ( const Manipulation::CalculationError& error )
In such cases they can be just empty classes without any additional error information unless you design allows those exceptions fly much upper where you catch all standard exceptions.
In my opinion it doesn't matter if you inherit from std::exception or not. For me the most important thing about defining exceptions are:
Having the exception class names be useful and clear.
Clearly documenting (writing comments) when exception will get thrown by a function or class method. This is the single biggest failure point in exception handling in my opinion.
It doesn't make a big difference, since std::runtime_error also inherits from std::exception. You could argue that runtime error conveys more information about the exception, but in practice, people often just derive from the base exception class.
Related
So I know that an exception class can inherit from the std exception library, but what exactly does an exception class do? It throws exceptions and handles them, but why should I use a class? Can an exception class handle more than 1 type of object?
There is no such thing as an "exception class" in C++; there are
no constraints with regards to the type of what you can throw
and catch. (throw 3.14159; is a perfectly legal C++
statement.) Good programming practice says that except in
special cases, you should throw objects which inherit from
std::exception, but this is not a requirement, and it's not
unusual for programs to throw an int to trigger the end of
program. (Calling exit doesn't invoke all of the destructors,
so the program throws an int, which is caught and returned in
main.)
This might be kind of a silly question, but in C++, when I want to throw an exception.. what do I throw?
Am I supposed to throw std::exception, or is that reserved by the standard library? Or should I throw a string or int? Or should I just throw whatever I feel is appropriate?
Throw a class that's derived from std::exception; if you #include <stdexcept>, you can pick from a number of ready-made, useful derived classes.
Deriving from std::exception allows your handlers to follow a recognizable style, as you can always use .what() to get a textual message. Don't throw primitive types, since they carry no semantic information.
Generally people don't throw std::exception directly for the simple reason that it doesn't store any error messages. There wouldn't be anything for the what method to return. I get confused sometimes over this because MSVC provides a non-standard extension to this a parameterized constructor in std::exception that accepts a string.
You can choose among existing exception classes like std::runtime_exception or define your own. This is somewhat subjective but I recommend keeping the number of exception classes to a minimum as RAII can eliminate a lot of the need to have multiple code branches and catch blocks for different exception types. Often the message combined with RAII-conforming code is enough to gracefully recover from any exception.
And finally, I recommend all exceptions you throw inherit from std::exception for similar reasons. You don't want to have to litter your code with many different catch blocks for different exception types if you can avoid it. Solve the problem as generally as you can.
The primary exception to throwing something derived from std::exception would be if you're using some framework (e.g., MFC) with its own exception hierarchy. In that case, you generally want to derive from an appropriate spot in their hierarchy instead.
Note that I'm not particularly attempting to hold MFC up as an example of clean exception handling (or clean design in general), only an example of a framework that includes an exception hierarchy. When you're using a framework that already defines an exception hierarchy, you're generally better off using it.
In other words, unlike the preference in C++ otherwise, it's generally accepted that exceptions should be a single, monolithic hierarchy with a single root. For the standard library, that single root is std::exception, but other frameworks have alternatives, and if they provide one you generally want to fit yours into it.
Unlike java you CAN throw whatever (int, string, MyClass, ...) you want. But listen to Kerrek. :)
Usually you'll want to throw one of the exceptions derived from std::exception as others have said.
On occasion I've thrown other types, but only if it's caught within the same block and the value is something useful in that context.
This is a picky thing and it is probably just my OCD flairing up but I was wondering why the standard exception class hierarchy is set up as it is.
exception
bad_alloc
bad_cast
bad_typeid
bad_exception
ios_base::failure
runtime_error
subclasses...
logic_error
subclasses...
Couldn't all the bad_* exceptions just be subclasses of something like lang_support_error? And ios_base::failure seems completely out of place.
Is there some historical or technical reasons the hierachy ended up like this?
If I remember correctly, the logic was:
logic_error would be the equivalent of an assert, but with less drastic behavior
runtime_error would be the base of all others
However, as you noticed, it does not quite hold, even in the standard library itself.
The main issue I guess is subjectivity: is std::out_of_range a logic_error or a runtime_error ?
It's subjective...
For a library code, is it better practice to create and throw custom exception class (library::Exception), or just throw standard exceptions (runtime_error, invalid_argument, etc.)?
It's usually better to specialize (inherit) a standard exception and throw it.
This way it'll be possible to catch it as a generic exception just by catching a std::exception, but you could also catch specifically your custom exception type if you need more specialized code.
Also see this C++Faq about what to throw.
Generally you should throw instances of classes in the stdexcept header or subclasses thereof. What class exactly makes sense depends on the specific problem. I think throwing instances of “category classes” std::logic_error and std::runtime_error is rarely useful since they carry no inherent meaning; they are used to distinguish the two main situations where exceptions can occur:
Subclasses of std::logic_error should be thrown by a function if it is called, but not all preconditions are fulfilled. The exception is the fault of the caller since it has failed to provide the necessary preconditions. For this category, you generally have to choose between throwing and undefined behavior; it is a trade-off between robustness and efficiently (e.g. std::vector::at() vs. std::vector::operator[]. These exceptions often cannot be handled; they are the result of bugs in the program.
Subclasses of std::runtime_error should be thrown by a function if all preconditions are met but the function cannot meet the postconditions or breaks invariants for reasons outside the control of the program (e.g., a file doesn’t exist, the network connection is lost, or not enough memory is available). These exceptions should usually be handled.
I think the available logic error classes (e.g. invalid_argument) are often good enough, because if they are raised, the code usually has to be fixed, and there is no reason for elaborate handling routines. On the other hand, the runtime error classes in the standard library are by their nature much less flexible and cover mainly the areas where the standard library itself has to throw exceptions. For your application, you should almost always inherit from these runtime error classes. For example, a class managing the operating system resource X should throw an X_creation_error which inherits from std::runtime_error if the constructor fails to allocate the resource.
Multiple virtual inheritance is often useful with exception classes. You can inherit from std::runtime_error or other stdexcept classes, from some “marker class” specific to your library, and from boost::exception to get the additional benefits of the Boost.Exception library. The Boost.Exception tutorial is highly recommended, especially Exception types as simple semantic tags and Using virtual inheritance in exception types.
IMHO Custom exception. The customers of your library will apreciate this. He will know whats exactly raises the exception.
From experience, it is rare that you need more than a very few exception classes.
In most of my code (mainly numerics -- if you do eg. IO, the situation is different), I throw standard exeptions (runtime_error, invalid_argument, ...) because they tend to indicate something that cannot be easily recovered from (except perhaps invalid_argument), and which will likely not be caught by user code (except perhaps at the top-level to throw a message box to the user).
If there is some exception which is intended to be caught by typical user code, eg. bad_custom_cast, or bad_market_data_identifier, instead of bubbling up to main (like a failure in a numerical routine, or bad_alloc), I make a custom class. But this is quite rare actually.
Question 1:
Is is possible to throw an exception that will not be caught by std::exception?
try
{
}
catch(std::exception & e)
{
}
catch(...)
{
//Is this block needed?
}
Question 2:
Is it better to have:
catch(std::exception & e)
Or
catch(std::exception e)
Or
catch(const std::exception &e)//<--- this is the method I usually use
Q1: yes. you can throw any type, not necessary types that inherit from std::exception.
you can write throw 1; to throw and int or throw "hello"; to throw a char*, both of which do not inherit from std::exception. this is however considered bad practice because the user of the class can't expect you to throw anything. If you don't want to inherit from std::exception what you usually do is create your own exception hierarchy.
Q2: catching an exception by value (2nd option) is a bad practice because you force the exception instance to be copied and in that possibly performing allocations which may cause further exceptions.
Using the first option suggest you intend to change e in the catch block which is also something you'd probably like to avoid because exceptions are usually maintained immutable after creation. The only thing that is left is the third option.
It sure is, you can throw any type you want, and it doesn't need to be derived from std::exception.
Catching a const reference is better. The reason is that you can throw a const or a non-const, and it can be caught by a non-const. Which works like a silent casting away of const.
The answer to your second question is that you should throw by value and catch by reference. If you catch by value you may get 'object slicing'.
It is sometimes necessary to throw an exception that does not inherit from std::exception. When shipping a shared library it's best practice to either re-implement or wrap most the std library types instead of exposing methods/functions that use them directly as it can cause all sorts of linker/compiler interoperability issues.