Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard or custom exception in C++?

Tags:

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.)?

like image 900
Daniel Langr Avatar asked Jan 20 '11 13:01

Daniel Langr


People also ask

Should I create custom exceptions?

You should only implement a custom exception if it provides a benefit compared to Java's standard exceptions. The class name of your exception should end with Exception. If an API method specifies an exception, the exception class becomes part of the API, and you need to document it.

What are custom exceptions?

In Java, we can create our own exceptions that are derived classes of the Exception class. Creating our own Exception is known as custom exception or user-defined exception. Basically, Java custom exceptions are used to customize the exception according to user need.

What are custom exceptions in C#?

Custom exceptions can be used to add clear, meaningful, and user-friendly information to exceptions when errors occur while your program is running. The base class for all exceptions in . Net is Exception . All of the classes in the exception hierarchy derive directly or indirectly from this class.

Where are standard exception classes?

Where are standard exception classes grouped? Explanation: As these are standard exceptions, they need to be defined in the standard block, So it is defined under namespace std.


2 Answers

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.

like image 20
Philipp Avatar answered Oct 23 '22 04:10

Philipp


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.

like image 161
peoro Avatar answered Oct 23 '22 06:10

peoro