I have some if, else_if, else blocks of code for different user input. The else at the end is for an invalid entry from the user. This is all part of a try block.
In the case the user makes an invalid entry I have to throw an exception. My prof already has this code prepared for the catch:
catch (char const* errormsg ) // for invalid item case
{code goes here }
Right now my else statement just looks like this:
else {
throw item;
}
I'm new to exception handling. Can somebody explain what I need to throw for the catch to catch it?
Since the code is designed to catch const char*s, and the argument has been called errormsg, it seems like the intent was for the exception object to be a C-style string containing the error message.
A string literal fits the bill:
throw "This is a description of the problem";
Note that this is bad practice; you should throw something of a descriptive type that derives from std::exception as a matter of convention.
Related
I'm sure this is something simple, but wasn't able to find any other posts clearly specifying this, though I'm sure there must be one buried somewhere.
In C++, when using a try catch block in the below manner, how can I append a string variable to the error message?
I get an unhandled exception when trying to do this. Is it something to do with what type is passed back? Appears to be returning a string versus a char*. if that is correct, would that cause the issue? How would I adjust for this? I tried adding an additional catch (const string my_msg), but that did not work, either.
string msg = "message";
try{
if (...)
throw "My error " + msg;
}
catch (const char* my_msg){
cerr << my_msg << endl;
}
"My error " + msg is an operation that concatenates a const char* string and an std::string. This operation results in a temporary variable of type std::string. Therefore, the thrown variable must be caught with a catch clause of type std::string.
catch (const std::string& my_msg){
cerr << my_msg << endl;
}
Still, it is better practice to have your exceptions derive from std::exception. You don't need to create your own exception class though, as there is std::runtime_error and its derivations, which provides useful classifications of common runtime exceptions.
There are many cases where you need to have a distinct type for your exceptions, often of which may be project or domain specific. In C++11, making your own exception type is as easy as this
struct my_exception : std::runtime_error {
using std::runtime_error::runtime_error; // Inherit runtime_error's constructors
};
This uses C++11's inheriting constructors.
So i'm doing a class Exception for linked list, but i have no idea what to put it in. For example, if the user wants to delete an element that does not exist in the list, it will print out "Sparse Exception caught: Element not found, delete fail", or "Sparse Exception caught: sparse matrix empty, printing failed". Is it ok for me to do it this way? If so, how do i print out the message?
SparseException::SparseException ()
{
}
SparseException::SparseException (char *message)
{
if (strcmp(message, "delete"))
cout << "Sparse Exception caught: Element not found, delete fail";
else
cout << "Sparse Exception caught: sparse matrix empty, printing failed";
}
void SparseException::printMessage () const
{
}
In my opinion an exception should always inherit std::exception or one of its subclasses. This will give you an idea of the interface you should implement. You need a what methods for instance(in fact what returns what probably your printMessage would print). Also if you really want to print your exception's what message, better overload the operator<<.
Inheriting std::exception is needed so that you know a catch(std::exception& ex) will catch any exception that your code threw.
Adding to #Ivaylo post, the line
if (strcmp(message, "delete"))
should read
if (0 == strcmp(message, "delete"))
Usually, exception classes simply contain information about what went wrong. Usually, they contain a string, because strings can contains about just everything you want "Writing 123 to file c:/a.txt failed".
In the simple case you present, you should rather use different classes of Exceptions (like a SparseDeleteException). Or, if you want to have more complex logic to get error texts, I would suggest to use a different class to handle "error id" -> "error string" conversions, because this is not the task of the exception.
Furthermore, the exception should have a method toString instead of print - the catching method should be able to decide what to do with the message.
So i'm doing a class Exception for linked list, but i have no idea what to put it in.
First, consider inheriting from std::exception hierarchy (usually I inherit from std::runtime_error or std::logic_error). It will provide you with a basic class receiving a string message that describes the error and allow your client code to receive and handle your exceptions by catching a generic std::exception ref.
For example, if the user wants to delete an element that does not exist in the list, it will print out "Sparse Exception caught: Element not found, delete fail", or "Sparse Exception caught: sparse matrix empty, printing failed". Is it ok for me to do it this way?
Normally you should use a complete message (a string that can be logged) that describes the error, but not the type of exception (leave that to your exception classes hierarchy).
in your case:
class SparseException: public std::runtime_error
{
public:
SparseException(const std::string& message): std::runtime_error(message) {}
};
Your queue:
// ...
if (whatever1)
throw SparseException("element not found, delete failed");
// ...
if (whatever2)
throw SparseException("sparse matrix empty, printing failed");
If so, how do i print out the message?
Client code:
try
{
// ...
} catch(const SparseException& e)
{
std::cerr << "SparseException: " << e.what() << "\n"; // what() is a member
// of std::exception
}
If you want to create a custom Exception, you'd better inherit it from std::exception or its subtypes like runtime_error or logic_error. Besides, it makes no sense to print message in the exception class, that's client's responsibility. You only need override what method, which returns detailed exception message(that said, runtime_error or logic_error's default implementation is usually OK).
Statement if (strcmp(message, "delete")) {...} makes little sense, too(actually it should be !strcmp(...)). If you just want to print different message, passing that message to the exception's constructor is enough. However, if you need distinguish exceptions, you'd better add some class like SparseDeletionException or SparseEmptyException that inherits from common base SparseException(which in turn inherits from std::exception).
I have read answers to following questions ->
c++ exception : throwing std::string
c++ Exception Class Design
My requirement is to catch exceptions and allow a mechanism to reformat the error messages and then re-throw the exceptions.
So I thought of writing my exception class which will provide a method to reformat the error message at various catch points.To make reformatting easy, I'm embedding a string object in myexception_base class.
I have also referred to this article -> http://www.boost.org/community/error_handling.html which clearly says not to embed string objects in exception classes.
The article also has a quote "Peter Dimov makes an excellent argument that the proper use of a what() string is to serve as a key into a table of error message formatters." but it does not elaborate on it any further.
I have written the code as given below and my questions are -
1) If I don't embed a string object in my exception class, it will make it difficult to reformat the what messages. Please tell me How shall I approach to my requirement without embedding a string object in my exception class?
2) If I carry on with my current approach of embedding a string object and providing a method to format error message. Is my way of handling some scenarios correct ? (Issue 1 and Issue 2 in which error msg doesn't get formatted)
Issue 1 - wrong exception getting propagated to catch points ?
Issue 2 - Error Message not getting formatted in some scenarios ?
Issue 1 and Issue 2 are mentioned in comments in code below.
Kindly have a look at the code. I have given lot of comments in code so lines of code has increased but if I remove the comments it has very less lines of code.
#include <string>
#include <exception>
#include <iostream>
using namespace std;
class myexception_base : public exception {
private:
string error_msg;
public:
myexception_base(const char* str) : error_msg(str) {
// std::string here here can throw an exception while error_msg
//initialisation through MIL.
// myexception_base object will not be constructed
// and wrong exception will be propagated to catch point(Issue 1)
}
const char* what() const throw() {
try {
return error_msg.c_str();
} catch (...) {}
// c_str can throw.
// I can't remove throw specification from what()
// because what() in base std::exception has throw() specification
// In case c_str() throws an exception program will terminate
// So to stop abnormal termination of program c_str
// is wrapped in a try catch block to ignore std::string exception
// program will not terminate but what message is not reformatted
// in such scenario (Issue 2)
}
void append_error_msg(const char* str) {
error_msg.append(str);
// append can throw
// Again error_msg will not be formatted (Issue 2)
}
~myexception_base() throw() {
}
};
void f();
void f2();
void f() {
throw myexception_base("Error Msg1");
}
void f2() {
//Some intermediate Catch point will reformat e.what() msg
//by appending an error msg2
try {
f();
}
catch (myexception_base& e) {
e.append_error_msg(": Error Msg2");
throw;
}
}
int main () {
try {
f2();
}
catch(const exception& e) {
// Finally the exception is caught in the upper most layer
// and proper error_msg is given to user
cout<<e.what()<<"\n";
}
}
According to the boost documentation embedding classes which might throw during their lifetime are not an excellent candidate to be used in the exception handler mechanism, so I would like to suggest that you will simply use the good old C way of handling strings. It will require some extra effort to bring it up and running but with them you have eliminated one source of error.
So, basically there are two approaches:
In the myexception_base you declare the error_msg as being an array of N chars. In the append_error_msg you carefully check that the length of the NEW string (after the append) is not greater than N and if it is not, then you use strcat or one of the other C string handling methods. This approach might be good, since it does not allow memory leaks through the exception handling mechanism, however you can have only a limited length of error message.
In the myexception_base you declare the error_msg as being a char* (a char pointer). In the constructor you callocmemory for it (do not use new since new might throw) and in the append_error_message you realloc the pointer to be the new size (ie. old size + string to be appended.size + 1 for the 0) and then memcpy to the requested position (ie. at the position of the end of the old string in the newly allocated string). Of course, do not forget to check all the allocations/re-allocations that they have returned a valid value otherwise you might get funny behavior. And last, but not least, to avoid the classical memory leaks, free the memory of the char* in the destructor.
Good luck!
I can do this, no problem:
long lngval = 3L;
int i = lngval;
but if I try this:
try {
throw 3L;
}
catch(int i) {
cout << "caught " << i << endl;
}
I get an unhandled exception.
This seems inconsistent. what is the reason for no type conversion in this case?
In the first case, the compiler can tell exactly what you want to do: convert a long to an int. In the second case, the compiler has to assume that you might have a construct like this:
try {
try {
throw 3L;
}
catch (int i) { /* P */ }
}
catch (long l) { /* Q */ }
The idea is that the compiler can never know whether there might be a catch (long l) lurking outside the current context, so it's never safe to just pick the first possible conversion.
This is also why it's common to use a class hierarchy when throwing exceptions rather than random types like int or long: it makes it easy to add more or less specification to your exception handlers in such a way that the compiler can be sure of your intentions (via the is-a relationship).
catch does not necessarily need the exact type.
It is common and good practice to use exceptions derived from std::exception (found in <stdexcept>). The reason is that you can then catch polymorphically, i.e. you do not need to know the exact type (see also Difference: std::runtime_error vs std::exception()) and that we have a convention to handle this.
Either you use one of the ones provided by the standard (e.g. std::range_error), or if nothing suits your problems [enough], specialize std::exception:
#include <stdexcept>
class moores_law_stopped : public std::exception {
public:
virtual ~moores_law_stopped() throw() {}
virtual const char *what() const throw() {
return "moores law stopped. duck under your table.";
}
};
#include <iostream>
int main () {
try {
throw moores_law_stopped();
} catch (std::exception const &e) {
std::cerr << "oh oh: " << e.what() << std::endl;
}
}
Output:
oh oh: moores law stopped. duck under your table.
The convention is to catch by reference or const reference, so that you get polymorphic behavior without fearing object slicing.
The catch statement catches an object (or a scalar variable in your cases) given its type, so if the type mismatch, it passes to the next catch statement (if there is one) or to the default exception receiver.
In your case, you could have a second catch statement catching long, and maybe somewhere else, so your catch statement won't catch anything.
To catch any exception, just use catch() {} :)
A single tip, better use exception class, or subclass it for you own need :)
You can also throw 3; - no problem.
int and long are different types. It's an advantage of the exception handling that you can tell the exceptions apart from looking at their type (one central try block can handle exceptions of various kinds from various places / a try block can handle just some kinds of exceptions, letting others propagate).
Also, it is recommended to throw one of the standard exceptions or derive a class from one of those. Then you could just catch (const std::exception&) if you just want to handle the exception and don't care about the particular type.
You can catch multiple types in one try-catch block. In order for the compiler to know which catch block to throw to, it must be able to match the exact type. Or it can have a default catch block -- catch (...) {}, but you won't be able to get at the value thrown in that case.
string receiveFromServer();
this function returns a string that was received from some server. If there was an error along the way (including protocol), i want to return a NULL string. However, this doesn't work in c++ (unlike java).
i tried:
string response = receiveFromServer();
if (response==NULL) {
cerr << "error recive response\n";
}
but its not legal.
Since an empty string is also legal to return, what can i return that will indicate the error?
thank you!
You can throw an exception to indicate an error.
try {
std::string response = receiveFromServer();
} catch(std::runtime_error & e) {
std::cerr << e.what();
}
Then you would need a throw std::runtime_error("Error receive response") somewhere in receiveFromServer().
It is often considered good practice (though some might disagree) to create your own exception-classes that derive from std::runtime_error to enable clients to catch your errors specifically.
You can either throw an exception (better way), or return boost::optional< string >, but then you have to check if the return value is valid (this is actually worse).
NULL has only a meaning when using pointers. In java strings are pointers so you can do that.
In C++, if you return an std::string, it must exist. So you have some possibilites
Throw an exception
Return a pair with a bool indicating the success
Return an empty string
Use a pointer (I strongly discourage that option)
Maybe you should try to handle with exceptions
try
{
string response = receiveFromServer();
}
catch (...)
{
cerr << "error recive response\n";
}
If you want to return an empty string you could also use the function
string::empty() to test if it is empty