Skip to content

Commit

Permalink
E.14 exception type examples for isocpp#1852 (isocpp#1857)
Browse files Browse the repository at this point in the history
* E.14

* clean-up

* add final

* Added words to dictionary

* cleanup

* fix typo

* Update CppCoreGuidelines.md
  • Loading branch information
bgloyer authored Jan 27, 2022
1 parent 369beb8 commit 43f2e34
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 56 deletions.
88 changes: 32 additions & 56 deletions CppCoreGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -15992,80 +15992,56 @@ Sometimes, [`finally()`](#Re-finally) can make such unsystematic cleanup a bit m

##### Reason

A user-defined type is unlikely to clash with other people's exceptions.
A user-defined type can better transmit information about an error to a handler. Information
can be encoded into the type itself and the type is unlikely to clash with other people's exceptions.

##### Example

void my_code()
{
// ...
throw Moonphase_error{};
// ...
}
throw 7; // bad

void your_code()
{
try {
// ...
my_code();
// ...
}
catch(const Bufferpool_exhausted&) {
// ...
}
}
throw "something bad"; // bad

##### Example, don't
throw std::exception{}; // bad - no info

Deriving from `std::exception` gives the flexibility to catch the specific exception or handle generally through `std::exception`:

void my_code() // Don't
class MyException : public std::runtime_error
{
public:
MyException(const string& msg) : std::runtime_error{msg} {}
// ...
throw 7; // 7 means "moon in the 4th quarter"
// ...
}
};

void your_code() // Don't
{
try {
// ...
my_code();
// ...
}
catch(int i) { // i == 7 means "input buffer too small"
// ...
}
}
// ...

##### Note
throw MyException{"something bad"}; // good

The standard-library classes derived from `exception` should be used only as base classes or for exceptions that require only "generic" handling. Like built-in types, their use could clash with other people's use of them.
Exceptions do not need to be derived from `std::exception`:

##### Example, don't
class MyCustomError final {}; // not derived from std::exception

void my_code() // Don't
{
// ...
throw runtime_error{"moon in the 4th quarter"};
// ...
}
// ...

void your_code() // Don't
{
try {
// ...
my_code();
// ...
}
catch(const runtime_error&) { // runtime_error means "input buffer too small"
// ...
}
}
throw MyCustomError{}; // good - handlers must catch this type (or ...)

**See also**: [Discussion](#Sd-???)
Library types derived from `std::exception` can be used as generic exceptions if
no useful information can be added at the point of detection:

throw std::runtime_error("someting bad"); // good

// ...

throw std::invalid_argument("i is not even"); // good

`enum` classes are also allowed:

enum class alert {RED, YELLOW, GREEN};

throw alert::RED; // good

##### Enforcement

Catch `throw` and `catch` of a built-in type. Maybe warn about `throw` and `catch` using a standard-library `exception` type. Obviously, exceptions derived from the `std::exception` hierarchy are fine.
Catch `throw` of built-in types and `std::exception`.

### <a name="Re-exception-ref"></a>E.15: Throw by value, catch exceptions from a hierarchy by reference

Expand Down
2 changes: 2 additions & 0 deletions scripts/hunspell/isocpp.dic
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ Murray93
mutex
mutexes
mx
MyCustomError
MyException
myMap
MyMap
myset
Expand Down

0 comments on commit 43f2e34

Please sign in to comment.