Difference: std::runtime_error vs std::exception() - c++

What is the difference between std::runtime_error and std::exception? What is the appropriate use for each? Why are they different in the first place?

std::exception is the class whose only purpose is to serve as the base class in the exception hierarchy. It has no other uses. In other words, conceptually it is an abstract class (even though it is not defined as abstract class in C++ meaning of the term).
std::runtime_error is a more specialized class, descending from std::exception, intended to be thrown in case of various runtime errors. It has a dual purpose. It can be thrown by itself, or it can serve as a base class to various even more specialized types of runtime error exceptions, such as std::range_error, std::overflow_error etc. You can define your own exception classes descending from std::runtime_error, as well as you can define your own exception classes descending from std::exception.
Just like std::runtime_error, standard library contains std::logic_error, also descending from std::exception.
The point of having this hierarchy is to give user the opportunity to use the full power of C++ exception handling mechanism. Since 'catch' clause can catch polymorphic exceptions, the user can write 'catch' clauses that can catch exception types from a specific subtree of the exception hierarchy. For example, catch (std::runtime_error& e) will catch all exceptions from std::runtime_error subtree, letting all others to pass through (and fly further up the call stack).
P.S. Designing a useful exception class hierarchy (that would let you catch only the exception types you are interested in at each point of your code) is a non-trivial task. What you see in standard C++ library is one possible approach, offered to you by the authors of the language. As you see, they decided to split all exception types into "runtime errors" and "logic errors" and let you proceed from there with your own exception types. There are, of course, alternative ways to structure that hierarchy, which might be more appropriate in your design.
Update: Portability Linux vs Windows
As Loki Astari and unixman83 noted in their answer and comments below, the constructor of the exception class does not take any arguments according to C++ standard. Microsoft C++ has a constructor taking arguments in the exception class, but this is not standard. The runtime_error class has a constructor taking arguments (char*) on both platforms, Windows and Linux. To be portable, better use runtime_error.
(And remember, just because a specification of your project says your code does not have to run on Linux, it does not mean it does never have to run on Linux.)

std::exception should be considered (note the considered) the abstract base of the standard exception hierarchy. This is because there is no mechanism to pass in a specific message (to do this you must derive and specialize what()). There is nothing to stop you from using std::exception and for simple applications it may be all you need.
std::runtime_error on the other hand has valid constructors that accept a string as a message. When what() is called a const char pointer is returned that points at a C string that has the same string as was passed into the constructor.
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}

Related

Decoupling exceptions from log formatting

In my API I have a small exception hierarchy, derived from std::exception. I have a base class Exception, which provides an error code, file, line, and function. Other more specific exceptions are derived from Exception. For example, one derived class adds a platform-specific error code, as well as a field that identifies which function returned the error code. This is like a simplified version of system_error, but I can't use C++11 features (I'm stuck working with VS2005, and no Boost).
I need to log these exceptions with my logging class. I want the exceptions to be logged in a certain format. After reading various forums online, and reading Boost's Error and Exception Handling Guidelines, I don't think the what function of each exception, or any other virtual function within Exception, is the appropriate place to format the exception for logging. Therefore my what functions just return the name of the class.
When catching exceptions, I often want to catch very general exceptions, usually std::exception, and pass it to the logger. I don't want to catch individual exceptions very often because I am trying to prevent exceptions from escaping the API (the public portion of my API is in C), and there may be several exceptions that could occur. I want to avoid code like:
try { /* blah */ }
catch {DerivedException const& ex) { logger.log(ex); }
...
catch {Exception const& ex) { logger.log(ex); }
So in my logging class, my log function accepts a std::exception argument. It then uses typeid to compare the parameter to the various exception classes, casting to the appropriate type and then calling a logging function specialized for that type of exception. This is essentially the same technique described in this other post.
I use typeid instead of dynamic_cast because dynamic_cast can succeed for any valid downcast, and for code maintenance purposes, I really don't want the order of my if statements in the log function to matter.
So is this a decent design? It feels wrong to me using typeid like this, but I think I have valid reasons to do it. I haven't seen much exception handling "in the wild", since we primarily work with C, so I haven't seen too many approaches to the subject. Are there other ways to decouple exceptions from their log formatting that I should be aware of?
EDIT: What I decided to implement
I took the suggestion of using the visitor pattern, but adapted it to my situation. I wanted to catch std::exception, since those can be thrown as well as my own, but format the log message based on the exception type.
Each of my exception classes derive from my base Exception class and implement the virtual function accept. I created an ExceptionLogger class, which implements an ExceptionVisitor interface providing the visit functions.
The LogFile class has an instance of ExceptionLogger, as well as an overload of its log function that takes an std::exception parameter. In the log function, I try a dynamic_cast to my base type, Exception. If it succeeds, I call the accept function of the exception, otherwise I call the ExceptionLogger::visit(std::exception const&) function directly. Since std::exception doesn't implement my accept function, I needed the dynamic_cast so I could determine if more detailed logging was possible.
I chose to do this instead of a series of if statements checking typeid because:
It's a named design pattern that I can refer future maintainers to
If a maintainer adds a new exception deriving from my Exception base, but forgets to implement a new visit function for that exception, I will still get the logging that was implemented for the base Exception - a file, line number, and function.
If I had implemented the series of if statements, I would've had to fall back to the std::exception logging behavior, which is just to print out the results of what, or I could've tried a dynamic_cast to an Exception.
Of course I would still prefer a compiler error in this situation.
A simpler solution is to rethrow your exception in your central formatting method (see also this answer). You can then catch each exception type there and format it.
class Exception : public std::exception {};
class DerivedException : public Exception {};
void LogThrownException();
void DoSomething()
{
try
{
// Do something, might throw ...
}
catch (...)
{
LogThrownException();
}
}
void LogThrownException()
{
try
{
throw;
}
// Order is important to catch all derived types.
// Luckily the compiler should warn, if a type is hidden.
catch (DerivedException&)
{
std::cout << "DerivedException";
}
catch (Exception&)
{
std::cout << "Exception";
}
catch (std::exception&)
{
std::cout << "std::exception";
}
// ...
catch (...)
{
std::cout << "Unknown\n";
}
}

Proper use of exceptions in C++

In C++ should I use std::runtime_error to indicate some sort of error occurred, or should I create custom exceptions that inherit from std::runtime_error so I can better handle them.
For example, if I got input from the user somehow, which would be better:
if (inputInvalid)
{
throw std::runtime_error("Invalid input!");
}
Versus...
class invalid_input
: public std::runtime_error /* or should I inherit from std::exception? */
{
public:
invalid_input()
: std::runtime_error("Invalid input!")
{
};
};
-------------------------------------------------------
if (inputInvalid)
{
throw invalid_input();
}
Which is considered better use of exception handling/which if better practice?
I would only subclass a standard exception class in one of two cases:
None of the standard exception classes have names that describe the nature of my exception
My exception needs additional information than what can be found in a standard exception (i.e. a string describing the error).
Otherwise, there's not much point. Especially if others will have to interact with your code and wonder why there is a custom exception class that doesn't do anything a standard exception doesn't.
Always think about what you gain from inheriting std::runtime_error. Does it let you handle the error easier? In the example code it doesn't give any benefits so no there is no point in inheriting from std::runtime_error if all it does is the same thing. If you want to add more information than what std::runtime_error has then you might want to inherit and add those to your error class.
That will depend on the size of the project. If your working on something small and just need something quick and dirty, std:runtime_error is fine. But if your working on a big project you are going to want to create your own custom exceptions to help manage(through catches) all the different possibilities. Otherwise now if you made a catch, you would be catching EVERYTHING, which may be a problem if you need to catch multiple different things with different ways to handle them.
I would also read this:
Difference: std::runtime_error vs std::exception()
I would subclass std::exception() for your invalid_input class in the example you gave. Typically, a user input error is not considered a runtime error, you may want to catch it earlier, you may want to perform different logic when it occurs. Using or subclassing in this case from runtime_exception in most cases fails the "is a" test.

How to make an intelligent decision about which standard exception to throw?

We know that the exception class has two derived classes: logic_error and runtime_error.
logic_error has four derived classes: domain_error, invalid_argument, length_error and out_of_range.
runtime_error has three derived classes: range_error, overflow_error and underflow_error.
While some of them are self-explanatory, like overflow_error and underflow_error, some are not that clear, especially range_error, both MSDN and cplusplus just say "to report a range error", which is close to saying nothing, how it is different out_of_range and domain_error???
Another question is when I throw an exception, which one should I choose? For example, In reverse_string(char* s), which exception to throw when s is NULL? In float calc_ellipse_area(float a, float b), which to throw when a or b is <=0? Which to throw when a == b (strictly speaking, circle is not an ellipse!)?
Finally, practically speaking, does it really matter if I throw an exception which is not correctly categorized?
A logic error is the (theoretically) result of a programmer error.
A runtime error is something that could not easily have been prevented by the programmer.
When you write a function, it is useful to document its preconditions and/or assumptions. If those preconditions are broken, it is a logic error.
A runtime error is usually due to something external: a file operation failed, a printer is offline, a DLL could not be loaded.
If a path parameter is malformed, that is a logic error. If it is a valid path string, but does not exist, or you don't have permission to access it, that is a runtime error.
Sometimes it becomes arbitrary. Bad user input is probably a runtime error, but failure to validate user input is more of a logic error. It may not be obvious which is the case in a particular situation.
If something starts in 01 Feb 2011, a finish date of "01 Jan 2011" is an invalid argument, while "31 Feb 2011" is out of range. A finish date of "fish and chips" is a domain error. Length errors are often about buffer size, but that might also include too much or too little input data or something like that.
A range error is similar to an out of range error, except for the context (runtime, not logic). e.g. Number of printers available = 0. Overflow and underflow are more or less self-explanatory.
In the end, use them in a way that you and your colleagues find meaningful -- or possibly don't use them at all. Some people just use std::exception for everything.
It is only really important if you are going to handle different exceptions differently. If you are just going to display (or log) a message and carry on, it doesn't matter what exception(s) you use.
For example, In reverse_string(char* s), which exception to throw when s is NULL?
In float calc_ellipse_area(float a, float b), which to throw when a or b is <=0? Which to throw when a == b (strictly speaking, circle is not an ellipse!)?
For both of these, use std::invalid_argument.
Or you can define your own exception called null_argument deriving from std::logic_error (or from std::invalid_argument), and use it for NULL argument.
The point is that if none of the standard exception class applies to your situation, or you want more specific exception, then define one deriving from existing classes.
For example, if you want to throw exception when you encounter an invalid index, then either you can use std::out_of_range or define more specific class called index_out_of_range deriving from std::out_of_range.
does it really matter if I throw an exception which is not correctly categorized?
Yes, it does matter. For example, it increases readability of your code. If you throw std::logic_error when an invalid index is encountered, then well, it doesn't add much to the readability, but instead of that if you throw std::out_of_range , then it greatly increases the readability. And if you throw index_out_of_range, it increases even more, as it's more specific.
From the standard:
The Standard C++ library provides classes to be used to report certain errors (17.6.5.12) in C++ programs. In the error model reflected in these classes, errors are divided into two broad categories: logic errors and runtime errors.
The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the program. In theory, they are preventable.
By contrast, runtime errors are due to events beyond the scope of the program. They cannot be easily predicted in advance.
However, all the exception types derived from runtime_error are misclassified -- all of them are easily preventable.
For actual runtime errors, the C++ standard library is rather inconsistent, it sometimes uses return values or internal state (e.g. iostream::bad(). And when it does use exceptions, they don't derive from runtime_error. For example, std::bad_alloc is a direct subclass of std::exception.
In conclusion, you shouldn't ever use std::runtime_error or any of its predefined subclasses.
The difference between out_of_range and range_error is found in the description of their parent classes:
logic_error: This class defines the type of objects thrown as exceptions to report
errors in the internal logical of the program. These are theoretically
preventable.
runtime_error: This class defines the type of objects thrown as exceptions to report
errors that can only be determined during runtime.
Domain error is for mathematical functions specifically. So your calc_ellipse_area could quite sensibly throw a domain error on negative value (and return 0 if one or both arguments are 0). I don't see any reason to complain if the ellipse happens to also be a circle, any more than a rectangle area function should fail on a square.
Passing null pointers to functions that shouldn't receive NULL I would handle by invalid argument exceptions.
C++ lets you throw whatever you like. What's really helpful to those who might use your code is that you name what you throw after the method signature, and that these names are reasonably descriptive. By default, a function could throw anything - to promise that a function won't throw, you have to use an empty throw() in the signature.

When throwing different kinds of exceptions is useful?

Is it useful to throw different exceptions for instance std::runtime_error or std::invalid_argument in huge projects? Or is it better to throw in general std::exception with a good text parameter for what()? And when does it make sence to derive some sub classes from std::exception?
Rumo
It always makes sense to use throw the most specific exception. As each exception should be derived from std::exception the code catching may decide at which level of granularity it wants to handle it (catch by reference! Item 13 in "More effective C++" from S. Meyers).
Using only std::exception with only some text a no-go:
unnecessary limiting the usage possibility of the catching code
the catching code would need to parse the text to base logic on if it had to perform different actions depending on the type of exception (whihc can be realized at lower cost with RTTI)
I cannot think of any case where it would be benefitiable to do so. Overriding what() provides an adequate text for any exception if you need.
I'd say that having a well thought hierarchy of exceptions is better than having only a single exceptions' type distinguished by its error message. This because you could write code like this:
try {
object.method();
}
catch (LogicalException& e) {
// if it's a LogicalException, handle it here
}
catch (Exception& e) {
// otherwise, handle a general exception here.
}
where LogicalException is-an Exception. Writing code like this in the other way would result in a long serie of if-else, very error-prone if you ask me.
All the Standard C++ exception classes are derived from the class std::exception. So, the catching code might catch the exception in std::exception & or with the specific clas handler but it makes more sense to throw the specific exception, so that the appropriate handler can handle the specific exception.
While I agree in principle that
It always makes sense to use throw the most specific exception
it may or may not be necessary.
I wrote the framework for a huge project and at first I was all gung ho on designing the mother of all error reporting systems -- it was gonna be beautiful. Part of the design was a hierarchy of exception classes.
And I chucked it all out. Not because it was bad, I chucked it because it was totally unnecessary.
We handled the existing exceptions of course, but there was no need for more than one custom exception because, as it turned out, every one of our "exceptional conditions" was what I call a "programmer" error, essentially a failed assertion.
The best solution in our case was a system which logged a discriptive trail of breadcrumbs to a file and then displayed the equivalent of "oops, sorry!" at the next appropriate idle state along with a link to tech support.
That was our app. Perhaps you are writing a library, in which case ignore everything I just said.
So -- sorry this sounds like a cop out -- but the answer to your question is:
It depends.

Should I inherit from std::exception?

I've seen at least one reliable source (a C++ class I took) recommend that application-specific exception classes in C++ should inherit from std::exception. I'm not clear on the benefits of this approach.
In C# the reasons for inheriting from ApplicationException are clear: you get a handful of useful methods, properties and constructors and just have to add or override what you need. With std::exception it seems that all you get is a what() method to override, which you could just as well create yourself.
So what are the benefits, if any, of using std::exception as a base class for my application-specific exception class? Are there any good reasons not to inherit from std::exception?
The main benefit is that code using your classes doesn't have to know exact type of what you throw at it, but can just catch the std::exception.
Edit: as Martin and others noted, you actually want to derive from one of the sub-classes of std::exception declared in <stdexcept> header.
The problem with std::exception is that there is no constructor (in the standard compliant versions) that accepts a message.
As a result I prefer to derive from std::runtime_error. This is derived from std::exception but its constructors allow you to pass a C-String or a std::string to the constructor that will be returned (as a char const*) when what() is called.
Reason for inheriting from std::exception is it "standard" base class for exceptions, so it is natural for other people on a team, for example, to expect that and catch base std::exception.
If you are looking for convenience, you can inherit from std::runtime_error that provides std::string constructor.
I once participated in the clean up of a large codebase where the previous authors had thrown ints, HRESULTS, std::string, char*, random classes... different stuff everywhere; just name a type and it was probably thrown somewhere. And no common base class at all. Believe me, things were much tidier once we got to the point that all the thrown types had a common base we could catch and know nothing was going to get past. So please do yourself (and those who'll have to maintain your code in future) a favor and do it that way from the start.
You should inherit from boost::exception. It provides a lot more features and well-understood ways to carry additional data... of course, if you're not using Boost, then ignore this suggestion.
Yes you should derive from std::exception.
Others have answered that std::exception has the problem that you can't pass a text message to it, however it is generally not a good idea to attempt to format a user message at the point of the throw. Instead, use the exception object to transport all relevant information to the catch site which can then format a user-friendly message.
The reason why you might want to inherit from std::exception is because it allows you to throw an exception that is caught according to that class, ie:
class myException : public std::exception { ... };
try {
...
throw myException();
}
catch (std::exception &theException) {
...
}
There is one problem with inheritance that you should know about is object slicing. When you write throw e; a throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw. That could be not what you're expecting. Example of problem you could find here.
It is not an argument against inheritance, it is just 'must know' info.
Difference: std::runtime_error vs std::exception()
Whether you should inherit from it or not is up to you. Standard std::exception and its standard descendants propose one possible exception hierarchy structure (division into logic_error subhierarchy and runtime_error subhierarchy) and one possible exception object interface. If you like it - use it. If for some reason you need something different - define your own exception framework.
Whether to derive from any standard exception type or not is the first question. Doing so enables a single exception handler for all standard library exceptions and your own, but it also encourages such catch-them-all handlers. The problem is that one should only catch exceptions one knows how to handle. In main(), for example, catching all std::exceptions is likely a good thing if the what() string will be logged as a last resort before exiting. Elsewhere, however, it's unlikely to be a good idea.
Once you've decided whether to derive from a standard exception type or not, then the question is which should be the base. If your application doesn't need i18n, you might think that formatting a message at the call site is every bit as good as saving information and generating the message at the call site. The problem is that the formatted message may not be needed. Better to use a lazy message generation scheme -- perhaps with preallocated memory. Then, if the message is needed, it will be generated on access (and, possibly, cached in the exception object). Thus, if the message is generated when thrown, then a std::exception derivate, like std::runtime_error is needed as the base class. If the message is generated lazily, then std::exception is the appropriate base.
Since the language already throws std::exception, you need to catch it anyway to provide decent error reporting. You may as well use that same catch for all unexpected exceptions of your own. Also, almost any library that throws exceptions would derive them from std::exception.
In other words, its either
catch (...) {cout << "Unknown exception"; }
or
catch (const std::exception &e) { cout << "unexpected exception " << e.what();}
And the second option is definitely better.
If all your possible exceptions derive from std::exception, your catch block can simply catch(std::exception & e) and be assured of capturing everything.
Once you've captured the exception, you can use that what method to get more information. C++ doesn't support duck-typing, so another class with a what method would require a different catch and different code to use it.
Though this question is rather old and has already been answered plenty, I just want to add a note on how to do proper exception handling in C++11, since I am continually missing this in discussions about exceptions:
Use std::nested_exception and std::throw_with_nested
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
You don't even need to subclass std::runtime_error in order to get plenty of information when an exception is thrown.
The only benefit I see in subclassing (instead of just using std::runtime_error) is that your exception handler can catch your custom exception and do something special. For example:
try
{
// something that may throw
}
catch( const MyException & ex )
{
// do something specialized with the
// additional info inside MyException
}
catch( const std::exception & ex )
{
std::cerr << ex.what() << std::endl;
}
catch( ... )
{
std::cerr << "unknown exception!" << std::endl;
}
Another reason to sub-class exceptions is a better design aspect when working on large encapsulated systems. You can reuse it for things such as validation messages, user queries, fatal controller errors and so on. Rather than rewriting or rehooking all of your validation like messages you can simply "catch" it on the main source file, but throw the error anywhere in your entire set of classes.
e.g. A fatal exception will terminate the program, a validation error will only clear the stack and a user query will ask the end-user a question.
Doing it this way also means you can reuse the same classes but on different interfaces. e.g. A windows application can use message box, a web service will show html and reporting system will log it and so on.