Creating custom exceptions in C++ - c++

I am learning C++ and I am experiencing when I try and create my own exception and throw them on Linux.
I've created a small test project to test my implementation and below is my exception class header file.
class TestClass : public std::runtime_error
{
public:
TestClass(char const* const message) throw();
virtual char const* what() const throw();
};
The source file for the exception class is
using namespace std;
TestClass::TestClass(char const* const message) throw()
: std::runtime_error(message)
{
}
char const * TestClass::what() const throw()
{
return exception::what();
}
In my main app, I am calling a function which throws my exception and catches it in a try/catch as follows:
void runAFunctionAndthrow();
/*
*
*/
int main(int argc, char** argv) {
try
{
cout << "About to call function" << endl;
runAFunctionAndthrow();
}
catch (TestClass ex)
{
cout << "Exception Caught: " << ex.what() << endl;
}
return 0;
}
void runAFunctionAndthrow()
{
cout << "going to run now. oh dear I need to throw an exception" << endl;
stringstream logstream;
logstream << "This is my exception error. :(";
throw TestClass(logstream.str().c_str());
}
When I run I'm expecting to get the following output:
About to call function
Going to run now. oh dear I need to throw an exception
Exception Caught: This is my exception error. :(
Instead what I am getting is
About to call function
going to run now. oh dear I need to throw an exception
Exception Caught: std::exception
Notice the last line it says std::exception instead of my actual exception message "This is my exception error".
Why is this, it works OK on Windows but on Linux it does this.
From what I've seen on various posts what I've done is correct so what am I missing.

Your what() returns:
return exception::what();
The return value from std::exception::what() is specified as follows:
Pointer to a null-terminated string with explanatory information.
That's it. Nothing more, nothing else. The text you're showing certainly qualifies as an "explanatory information". And this is the only requirement for the return value of what() (except for one other one which is not germane here).
In other words, C++ does not guarantee the exact contents of what you get with what(). what() you see is what() you get, as the saying goes.
If you want your exception to describe itself, in some way, it's up to you to implement that, as part of your what().

You need your own implementation of what() method or use std::runtime_error::what() as written in comments
Say:
class TestClass : public std::runtime_error
{
std::string what_message;
public:
const char* what() override
{
return what_message.c_str();
}
};
Also, better use noexcept instead of throw() and only after you read about them - link.
And in your try-catch:
catch (const TestClass& myException)
Instead of catch(TestClass myException) - otherwise you do an implicit copy which can potentially result in an exception throw. It also breaks the polymorphism: if you want to catch pure virtual interface implementation instance, you would need to use a reference.

You need a way to specify a custom error message to std::exception which afaik is not allowed. See this for a possible solution.

First of most of the info about the answer had been given by Sam Varshavchik
But I want to add one thing
When throwing and catching A good rule is
"Throw by value catch by reference "
So your throw was fine as:
void runAFunctionAndthrow()
{
cout << "going to run now. oh dear I need to throw an exception" << endl;
stringstream logstream;
logstream << "This is my exception error. :(";
throw **TestClass(logstream.str().c_str())**;
}
used an implicit conversion to TestClass and then it got passed by value.
the Key point in that rule is to minimize memory allocating handling between different stack frames
your catch on the other hand dosen't follow the rule (since you catch by value):
catch (TestClass ex)
{
cout << "Exception Caught: " << ex.what() << endl;
}
the catch should be (const TestClass& ex)
the key point in this rule is implicit conversion between base class and derived class.

Related

Catching exceptions in class constructor C++ [duplicate]

I have a very poor understanding of exception handling(i.e., how to customize throw, try, catch statements for my own purposes).
For example, I have defined a function as follows: int compare(int a, int b){...}
I'd like the function to throw an exception with some message when either a or b is negative.
How should I approach this in the definition of the function?
Simple:
#include <stdexcept>
int compare( int a, int b ) {
if ( a < 0 || b < 0 ) {
throw std::invalid_argument( "received negative value" );
}
}
The Standard Library comes with a nice collection of built-in exception objects you can throw. Keep in mind that you should always throw by value and catch by reference:
try {
compare( -1, 3 );
}
catch( const std::invalid_argument& e ) {
// do stuff with exception...
}
You can have multiple catch() statements after each try, so you can handle different exception types separately if you want.
You can also re-throw exceptions:
catch( const std::invalid_argument& e ) {
// do something
// let someone higher up the call stack handle it if they want
throw;
}
And to catch exceptions regardless of type:
catch( ... ) { };
Though this question is rather old and has already been answered, I just want to add a note on how to do proper exception handling in C++11:
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"
Just add throw where needed, and try block to the caller that handles the error. By convention you should only throw things that derive from std::exception, so include <stdexcept> first.
int compare(int a, int b) {
if (a < 0 || b < 0) {
throw std::invalid_argument("a or b negative");
}
}
void foo() {
try {
compare(-1, 0);
} catch (const std::invalid_argument& e) {
// ...
}
}
Also, look into Boost.Exception.
You could define a message to throw when a certain error occurs:
throw std::invalid_argument( "received negative value" );
or you could define it like this:
std::runtime_error greatScott("Great Scott!");
double getEnergySync(int year) {
if (year == 1955 || year == 1885) throw greatScott;
return 1.21e9;
}
Typically, you would have a try ... catch block like this:
try {
// do something that causes an exception
}catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; }
Adding to this answer, as it doesn't seem advantageous to create another answer for this Q&A at this time.
In the case where you create your own custom exception, that derives from std::exception, when you catch "all possible" exceptions types, you should always start the catch clauses with the "most derived" exception type that may be caught. See the example (of what NOT to do):
#include <iostream>
#include <string>
using namespace std;
class MyException : public exception
{
public:
MyException(const string& msg) : m_msg(msg)
{
cout << "MyException::MyException - set m_msg to:" << m_msg << endl;
}
~MyException()
{
cout << "MyException::~MyException" << endl;
}
virtual const char* what() const throw ()
{
cout << "MyException::what" << endl;
return m_msg.c_str();
}
const string m_msg;
};
void throwDerivedException()
{
cout << "throwDerivedException - thrown a derived exception" << endl;
string execptionMessage("MyException thrown");
throw (MyException(execptionMessage));
}
void illustrateDerivedExceptionCatch()
{
cout << "illustrateDerivedExceptionsCatch - start" << endl;
try
{
throwDerivedException();
}
catch (const exception& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an std::exception, e.what:" << e.what() << endl;
// some additional code due to the fact that std::exception was thrown...
}
catch(const MyException& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an MyException, e.what::" << e.what() << endl;
// some additional code due to the fact that MyException was thrown...
}
cout << "illustrateDerivedExceptionsCatch - end" << endl;
}
int main(int argc, char** argv)
{
cout << "main - start" << endl;
illustrateDerivedExceptionCatch();
cout << "main - end" << endl;
return 0;
}
NOTE:
The proper order should be vice-versa, i.e.- first you catch (const MyException& e) which is followed by catch (const std::exception& e).
As you can see, when you run the program as is, the first catch clause will be executed (which is probably what you did NOT want in the first place).
Even though the type caught in the first catch clause is of type std::exception, the "proper" version of what() will be called - cause it is caught by reference (change at least the caught argument std::exception type to be by value - and you will experience the "object slicing" phenomena in action).
In case that the "some code due to the fact that XXX exception was thrown..." does important stuff WITH RESPECT to the exception type, there is misbehavior of your code here.
This is also relevant if the caught objects were "normal" object like: class Base{}; and class Derived : public Base {}...
g++ 7.3.0 on Ubuntu 18.04.1 produces a warning that indicates the mentioned issue:
In function ‘void illustrateDerivedExceptionCatch()’:
item12Linux.cpp:48:2: warning: exception of type ‘MyException’ will be caught
catch(const MyException& e)
^~~~~
item12Linux.cpp:43:2: warning: by earlier handler for ‘std::exception’
catch (const exception& e)
^~~~~
Again, I will say, that this answer is only to ADD to the other answers described here (I thought this point is worth mentioning, yet could not depict it within a comment).

How to forward a thrown expression from one catch block to another?

I am writing a program in C++ which handles errors via throwing strings (either std::string or const char*), like so :
if (/* failure condition 1 */)
throw std::string("Error 1 : ...") + std::to_string(foo);
if (/* failure condition 2 */)
throw "Error 2 : ...";
Then I would catch them this way :
try {
thisIsLikelyToThrowErrors();
} catch (const std::string& e) {
std::cerr << ":( " << e << std::endl;
} catch (const char* e) {
std::cerr << ":( " << e << std::endl;
}
I would like to avoid writing the same line twice, by forwarding the string from the first catch block to the second one :
try {
thisIsLikelyToThrowErrors();
} catch (const std::string& e) {
throw e.c_str(); // Does not work
} catch (const char* e) {
std::cerr << ":( " << e << std::endl;
}
However this code won't work, the thrown char const* simply won't be catched.
Is there a way to do this?
Thanks :)
No, you cannot do this.
[C++14: 15.1/1]: When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3); “nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited.
You would have to nest entire try/catch pairs:
try {
try {
thisIsLikelyToThrowErrors();
}
catch (const std::string& e) {
throw e.c_str(); // Does not work
}
}
catch (const char* e) {
std::cerr << ":( " << e << std::endl;
}
Ew!
But now you have another problem, in that the std::string e dies after you've thrown its C-string buffer (it'd stay alive if you re-threw it). Probably try to avoid this in general, eh?
Throw actual exceptions, instead.
You can handle the common setup in an independent function externally, calling it from your catches clauses.
In your example, you can do:
inline void HandleStringyException(const char* excStr)
{
//do something
}
Then:
try {
thisIsLikelyToThrowErrors();
} catch (const std::string& e) {
HandleStringyException(e.c_str());
} catch (const char* e) {
HandleStringyException(e);
}
P.S. It should be mentioned that exceptions are better to be handled polymorphically, and in order to do so, the objects thrown should be chosen wisely. As mentioned by others, throwing objects like strings and pointers is a bad practice, and generally you'd like to throw objects derived from std::exception. Sometimes, however, the throwing code is not under your control and you have to make the best of it. I think that's a different discussion.
There is a simple solution to your actual problem:
Throw only std::string or only const char*.
Or even better throw something derived from std::exception

Runtime exception messages without extending std::exception

I have some code like this:
class ParseError: public exception {
protected:
mutable string msg;
int position;
public:
explicit ParseError(const string& message, const int index) {
msg = message;
position = index;
}
virtual ~ParseError() throw () {
}
const char * what() const throw () {
stringstream ss(msg);
ss << "Parse error at position " << position << ": " << msg;
msg = ss.str();
return msg.c_str();
}
};
When I throw it, I see something like this when running unit tests under valgrind:
foo.h:102: Unexpected exception with message: 'Parse error at position 9: Found unexpected character(s): blah'
This is what I want, but I was curious what the exception base class is doing behind the scenes. If I don't extend exception but leave the rest of the class as-is, I get this:
foo.h:102: Unexpected exception with message: 'Unknown exception'
What would I need to add to my class in order to be able to not extend exception and still have the message show up?
By the way, I realize that I should probably be extending runtime_error rather than exception. In this case, I'm curious what makes exception tick behind the scenes, I'm not necessarily looking for advice on best practices.
There is no guarantee that you'll get a useful error message if you don't handle an exception; the only guarantee is that the program will be terminated by calling std::terminate.
It seems that your implementation is able to identify that the unhandled exception was derived from std::exception, and use that knowledge to call its override of what() to generate an error message. It would know nothing about non-standard exception types, and it shouldn't randomly call functions just because they happen to have the same name as a function in a completely unrelated class.
If you want to print something useful when an arbitrary type is thrown, you'll need a handler to catch that type and do the right thing with it. But I would definitely advise you to only throw types derived from std::exception unless you've got a very good reason to throw something else.
Two problems here:
In this function you putting msg to itself:
const char * what() const throw () {
stringstream ss(msg);
** ^^^
ss << "Parse error at position " << position << ": " << msg;
** ^^^
But this is not very important since your second problem is that you should move creating message from what() to constructor. what()should only returns it.
class ParseError: public exception {
protected:
string msg;
public:
explicit ParseError(const string& message, const int index) {
ostringstream ss;
ss << "Parse error at position " << position << ": " << message;
msg << ss.str();
}
const char * what() const throw () {
return msg.c_str();
}
};

How to throw a C++ exception

I have a very poor understanding of exception handling(i.e., how to customize throw, try, catch statements for my own purposes).
For example, I have defined a function as follows: int compare(int a, int b){...}
I'd like the function to throw an exception with some message when either a or b is negative.
How should I approach this in the definition of the function?
Simple:
#include <stdexcept>
int compare( int a, int b ) {
if ( a < 0 || b < 0 ) {
throw std::invalid_argument( "received negative value" );
}
}
The Standard Library comes with a nice collection of built-in exception objects you can throw. Keep in mind that you should always throw by value and catch by reference:
try {
compare( -1, 3 );
}
catch( const std::invalid_argument& e ) {
// do stuff with exception...
}
You can have multiple catch() statements after each try, so you can handle different exception types separately if you want.
You can also re-throw exceptions:
catch( const std::invalid_argument& e ) {
// do something
// let someone higher up the call stack handle it if they want
throw;
}
And to catch exceptions regardless of type:
catch( ... ) { };
Though this question is rather old and has already been answered, I just want to add a note on how to do proper exception handling in C++11:
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"
Just add throw where needed, and try block to the caller that handles the error. By convention you should only throw things that derive from std::exception, so include <stdexcept> first.
int compare(int a, int b) {
if (a < 0 || b < 0) {
throw std::invalid_argument("a or b negative");
}
}
void foo() {
try {
compare(-1, 0);
} catch (const std::invalid_argument& e) {
// ...
}
}
Also, look into Boost.Exception.
You could define a message to throw when a certain error occurs:
throw std::invalid_argument( "received negative value" );
or you could define it like this:
std::runtime_error greatScott("Great Scott!");
double getEnergySync(int year) {
if (year == 1955 || year == 1885) throw greatScott;
return 1.21e9;
}
Typically, you would have a try ... catch block like this:
try {
// do something that causes an exception
}catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; }
Adding to this answer, as it doesn't seem advantageous to create another answer for this Q&A at this time.
In the case where you create your own custom exception, that derives from std::exception, when you catch "all possible" exceptions types, you should always start the catch clauses with the "most derived" exception type that may be caught. See the example (of what NOT to do):
#include <iostream>
#include <string>
using namespace std;
class MyException : public exception
{
public:
MyException(const string& msg) : m_msg(msg)
{
cout << "MyException::MyException - set m_msg to:" << m_msg << endl;
}
~MyException()
{
cout << "MyException::~MyException" << endl;
}
virtual const char* what() const throw ()
{
cout << "MyException::what" << endl;
return m_msg.c_str();
}
const string m_msg;
};
void throwDerivedException()
{
cout << "throwDerivedException - thrown a derived exception" << endl;
string execptionMessage("MyException thrown");
throw (MyException(execptionMessage));
}
void illustrateDerivedExceptionCatch()
{
cout << "illustrateDerivedExceptionsCatch - start" << endl;
try
{
throwDerivedException();
}
catch (const exception& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an std::exception, e.what:" << e.what() << endl;
// some additional code due to the fact that std::exception was thrown...
}
catch(const MyException& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an MyException, e.what::" << e.what() << endl;
// some additional code due to the fact that MyException was thrown...
}
cout << "illustrateDerivedExceptionsCatch - end" << endl;
}
int main(int argc, char** argv)
{
cout << "main - start" << endl;
illustrateDerivedExceptionCatch();
cout << "main - end" << endl;
return 0;
}
NOTE:
The proper order should be vice-versa, i.e.- first you catch (const MyException& e) which is followed by catch (const std::exception& e).
As you can see, when you run the program as is, the first catch clause will be executed (which is probably what you did NOT want in the first place).
Even though the type caught in the first catch clause is of type std::exception, the "proper" version of what() will be called - cause it is caught by reference (change at least the caught argument std::exception type to be by value - and you will experience the "object slicing" phenomena in action).
In case that the "some code due to the fact that XXX exception was thrown..." does important stuff WITH RESPECT to the exception type, there is misbehavior of your code here.
This is also relevant if the caught objects were "normal" object like: class Base{}; and class Derived : public Base {}...
g++ 7.3.0 on Ubuntu 18.04.1 produces a warning that indicates the mentioned issue:
In function ‘void illustrateDerivedExceptionCatch()’:
item12Linux.cpp:48:2: warning: exception of type ‘MyException’ will be caught
catch(const MyException& e)
^~~~~
item12Linux.cpp:43:2: warning: by earlier handler for ‘std::exception’
catch (const exception& e)
^~~~~
Again, I will say, that this answer is only to ADD to the other answers described here (I thought this point is worth mentioning, yet could not depict it within a comment).

unexpected exceptions

I am trying to use the following code to test "set_unexpected()". I expect the code will generate an output like:
In function f(), throw const char* object
Call to my_unexpected
Exception in main(): Exception thrown from my_unexpected
But I got a run-time error: "This application has requested the Runtime to terminate it in an unusual way." So, what would be the problem? Thanks
struct E {
const char* message;
E(const char* arg) : message(arg) { }
};
void my_unexpected() {
cout << "Call to my_unexpected" << endl;
throw E("Exception thrown from my_unexpected");
}
void f() throw(E) {
cout << "In function f(), throw const char* object" << endl;
throw("Exception, type const char*, thrown from f()");
}
int _tmain(int argc, _TCHAR* argv[])
{
set_unexpected(my_unexpected);
try {
f();
}
catch (E& e) {
cout << "Exception in main(): " << e.message << endl;
}
return 0;
}
Visual C++ does not implement correctly exception specifications. As stated here,
Visual C++ departs from the ANSI Standard in its implementation of exception specifications.
and in particular
throw(type) - The function can throw an exception of type type. However, in Visual C++ .NET, this is interpreted as throw(...).
Also here:
Function exception specifiers other than throw() are parsed but not used.
Because of this, your terminate handler is never called, and since no handlers for const char * are present in your code the exception is not caught and the application terminates abnormally.
Anyway, keep in mind that exception specifications different from throw() are generally considered a bad idea, and actually the new C++ standard (C++11) deprecates them, introducing noexcept for what throw() was used.