I am trying to create a custom exception class, throw it, and display the error message, but I am doing something wrong, causing the exception to not get thrown and the message to not get printed.
Here's the exception class:
class UnbalancedParenthesesException : public std::exception {
int line_number {0};
public:
UnbalancedParenthesesException(int line_number) :
line_number { line_number }
{}
virtual const char* what() const throw() {
std::string exception_message =
"Papentheses imbalance at line " + std::to_string(line_number) + "\n";
return exception_message.c_str();
}
};
I am trying totry/throw/catch as follows:
void handle_closed_paren(int line_number) {
try {
if (definitely_unbalanced()) {
throw UnbalancedParenthesesException(line_number);
}
} catch (const UnbalancedParenthesesException& e) {
std::out << e.what() << "\n";
}
There is nothing pertinent to this error in the console.
Thanks in advance.
Your what() method is creating a local std::string variable and then returning a pointer to its internal data, which will be left dangling when the std::string goes out of scope and is destroyed when what() exits.
You need to store your error message in a std::string that is a member of the class so it does not go out of scope prematurely. Fortunately, std::exception already has an internal std::string for that purpose. So, instead of formatting the error message in what() itself, you should format it in your derived constructor and pass it to the base class constructor, letting the base what() method return it as-is:
class UnbalancedParenthesesException : public std::exception
{
int mLineNumber;
public:
UnbalancedParenthesesException(int line_number) : std::exception("Parentheses imbalance at line " + std::to_string(line_number)), mLineNumber(line_number) {}
// optional, if the catcher needs access to the value
int lineNumber() const { return mLineNumber; }
};
Your program has undefined behaviour as you are returning the result of c_str() on a std::string that goes out of scope. Anything could happen.
Beyond that, if you're not seeing an exception then one was not thrown, probably because the result of definitely_unbalanced() is falsey.
Step through your program using your debugger.
Related
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.
This is a (modified) problem from a test last week.
I was given an exception class with a predefined number in it:
class ErrorException {
/**
* Stub class.
*/
private :static long ErrorCode;
public: ErrorException( string str) {
cout <<str;
}
};
long ErrorException::ErrorCode = -444;
I think I was supposed to do was catch the exception and then return the number as an error code, but I could not figure out how to get the number in. I could make the catch return a string but not the number as string:
#include "stdafx.h"
#include <iostream>
#include "ErrorException.h"
#include "errno.h""
#include <string>;
class FillerFunction {
public :
virtual int getFillerFunction(int x) throw (ErrorException) = 0;
} // this notation means getFillerFunction is always throwing ErrorException?
double calculateNumber(int y){
//.....
try{
if (y !=0){
throw(ErrorException(?????))
}
};
double catchError(){
catch(ErrorException& x);
};
I eventually made it return the string "error" which is no better than using an if statement. I've looked up other catch-throw examples in c++ and dynamic exceptions, but I can't find an example with an exception grabbing a variable defined in the class.How do I access the ErrorCode, save changing the return type of ErrorException()?
Though this question has already been answered, I just want to add a few notes on proper exception handling in C++11:
First, throw(ErrorException) should not be used, as it is deprecated: http://en.cppreference.com/w/cpp/language/except_spec
Also, it is generally advisable to make use of the fact that C++ provides standard exception classes, personally I usually derive from std::runtime_error.
In order to really take advantage of the exception mechanism in C++11, I recommend using std::nested_exception and std::throw_with_nested as described on StackOverflow here and here. Creating a proper exception handler will allow you to get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging. Since you can do this with your 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"
In your throw you're constructing an exception object. If you prefer to pass a number, you must provide the appropriate constructor.
Quick and dirty:
class ErrorException {
private :
static long ErrorCode;
public:
ErrorException( string str) {
cerr <<str<<endl;
}
ErrorException( long mynumeric code) {
cerr <<"error "<<mynumericcode<<endl;
}
};
The catching should look like:
double calculateNumber(int y){
try {
if (y !=0){
throw(ErrorException(227));
}
} catch(ErrorException& x) {
cout << "Error catched"<<endl;
}
}
Must be elaborated further
It's unusual to to print something in the exception constructor. You'd better populate the information needed in the catch, so that these information could later be accessed with the appropriate getter. The printing would then occur in the exception handler.
If you have a static error code, I suppose that somewhere you have a function that returns the last error code whatever happened. So maybe you'd update this code (but how do you intend to update it with the existing string alternative ?
Here how it could look like:
class ErrorException {
private :
static long LastErrorCode;
long ErrorCode;
string ErrorMessage;
public:
ErrorException(long ec, string str) : ErrorCode(ec), ErrorMessage(str)
{
LastErrorCode = ec;
}
static long getLastError() const { return LastErrorCode; } // would never be reset
long getError() const { return ErrorCode; }
string getMessage() const { return ErrorMessage; }
};
The catching should look like:
double calculateNumber(int y){
try {
if (y !=0){
throw(ErrorException(227,"y is not 0"));
}
} catch(ErrorException& x) {
cerr << "Error "<<x.getError()<<" : "<<x.getMesssage()<<endl;
}
cout << "Last error ever generated, if any: " << ErrorException::getLastErrror()<<endl;
}
Neverthesess, I'd advise you to have a look at std::exception before reinventing the wheel.
This question is similar to c++ Exception Class Design and follows:
I want to design exception class hierarchy for my application and here are the design points I used:
Exception should be derived from standard exception classes (those are std::exception, std::logic_error and std::runtime_error).
Exception class should be able to take error description (i.e. what is called what) and position where it occurred (const std::string &file, int line)
Exception should not throw any exception during construction or from any other member.
Given this I have:
#define throw_line(TException, what) throw TException((what), __FILE__, __LINE__)
class AnException : public std::exception {
public:
AnException(const std::string &what, const std::string &file, int line) noexcept {
try {
what_ = what;
file_ = file;
line_ = line;
} catch (std::exception &e) {
was_exception_ = true;
}
}
virtual ~AnException() noexcept {}
virtual const char *what() const noexcept override {
if (was_exception_) {
return "Exception occurred while construct this exception. No further information is available."
} else {
try {
std::string message = what_ + " at " + file_ + ":" + std::to_string(line);
return message.c_str();
} catch (std::exception &e) {
return "Exception occurred while construct this exception. No further information is available."
}
}
}
};
class ParticularException : public AnException {
...
}
As you can see, it appears to be somewhat complex to construct such class, because we definitely should not have exceptions in constructor (otherwise std::terminate() will be called) or in what() member.
The question: is this example of a good design or I should remove some restrictions (like, having file/line information) to simplify it? Is there a better way?
I'm free to use C++11/C++14, but trying to keep off C++17 since it is not yet finished and compilers may not fully implement it.
Note: I want this code to be cross-platform.
Thanks in advance.
Edit 1: The follow up question: how can I retire file/line information, but keep that in logs? May be printing stacktrace is a better solution than what I have now? I mean leave exception class which just holds an error message (what) and call something like print_backtrace on upper level of exception handling chain.
Relating to my comment, depending on whether a what literal is acceptable, I had something like this in mind:
#include <array>
template <int N> constexpr std::size_t arraySize(const char (&)[N]){return N;}
template <class ExceptT, std::size_t whatN, std::size_t fileN>
class MyExcept : public ExceptT
{
static_assert(std::is_base_of<std::exception, ExceptT>::value, "bad not base");
public:
MyExcept(
const char (&what)[whatN],
const char (&file)[fileN],
int line) noexcept
: ExceptT(""), //Using our own what
what_(), file_(), line_(line)
{
std::copy(std::begin(what), std::end(what), begin(what_));
std::copy(std::begin(file), std::end(file), begin(file_));
}
virtual const char *what() const noexcept override
{
//....
}
private:
std::array<char,whatN> what_;
std::array<char,fileN> file_;
int line_;
};
#define throw_line(TException, what) throw MyExcept<TException,arraySize(what),arraySize(__FILE__)>(what,__FILE__, __LINE__)
void driver()
{
throw_line(std::runtime_error, "Hoo hah");
}
I've added some code that allows deriving from a std::exception type (type requires constructor with single literal argument (could check that this is also noexcept). I'm passing it an empty string literal, so std::exception class should at least not throw. I'm using static_assert to check this.
it cannot throw on construction...
it derives from std::exception...
it contains "fixed" what and position
This usually happens only, if you want to catch certain errors in another catch-block than your most outer catch block. I would only start doing this, if I see a demand. I remember that my system-call-read() wrapper would throw a different exception for EOF -- since this sometimes need to be caught.
Then I've got a system-error-exception and a normal message exception, since std::exception does not store any message with certain compilers.
Separate classes for exceptions are overused in the same way throw-specifications were overused.
Please remember that if you want to catch a certain error somewhere else than in the outer-most-catch-block, you need to be able to do something about the error, other than re-throw it. Usually the string returned from what() should already be sufficient to tell you what kind of error occurred. Thus for printing reasons there is no need to overload the exception type.
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();
}
};
The following code works just fine:
#include <exception>
using namespace std;
class FileException : public exception { // error occurs here
int _error;
// string _error; <-- this would cause the error
public:
FileException(int error);
// FileException(string error);
const char* what() const throw();
};
But as soon as I change the type of _error to string, the following compile error occurs:
Exception specification of overriding function is more lax than base version
The destructor of std::string is not no-throw, which causes the implicit destructor of FileException not no-throw either. But the destructor of std::exception is no-throw, thus there's a compiler error.
You could declare an explicit no-throw destructor:
virtual ~FileException() throw() {}
or just inherit from std::runtime_error instead of std::exception, which has a constructor that takes std::string input.
Simplify with:
// Derive from std::runtime_error rather than std::exception
// std::runtime_error (unlike std::exception) accepts a string as an argument that will
// be used as the error message.
//
// Note: Some versions of MSVC have a non standard std::exception that accepts a string
// Do not rely on this.
class FileException : public std::runtime_error
{
public:
// Pass error msg by const reference.
FileException(std::string const& error)
// Pass the error to the standard exception
: std::runtime_error(error)
{}
// what() is defined in std::runtime_error to do what is correct
};
I approve of the above method,
but g++ seems to complain if
the default constructor is not present.
The following addition makes things work:
using namespace std;
class MyException : public runtime_error {
public:
/* add the following line: */
MyException() : runtime_error("MyException") { } // default constructor
MyException( string const& error ) : runtime_error(error) { } // ctor w/string
};
additionally, an exception list is easily created:
MyException FileNotFound ( "File Not Found" );
MyException ReadOnly ( "ReadOnly" );
MyException Unkown ( "Unknown" );
...
throw FileNotFound;
...
when catching these exceptions, if you don't need specificity catch them generically:
catch( runtime_error re) { cout << "Runtime Error: " << re.what() << endl; ... }
Since all MyExceptions decend from runtime_error this catches them all and
you won't miss any other runtime errors from the system either.
catch( exception e) { cout << "exception: " << e.what() << endl; ... }
catches them all.
In C++, you can also throw and catch any types (int, booleans,pointers, etc.) Its sometimes simpler
to just throw/catch a string or an int within a function block.
Multiple classes should only throw and catch code library standard exceptions and their subclasses, (and all in the same manner), however, mostly for consistency and maintenance, but also because c++ compilers know how to optimize the exception mechanisms and linkages for them, and can generate intelligent warnings and errors about them, easing debugging.
"Error: "0x137F" is for IBM guys, not "the third guy on the project this year" ...