I am working on a small c++ program and learning exceptions. Is the following code \"bad\", and if so, what can I do to improve it?
try {
// code
if
std::exception (or at least, std::runtime_error) contains a string, that can be accessed through the what() method. Best thing you can do is to use that, since it's standard, and other code can expect it, and since it serves your purpose anyway.
Better stick to the standard in this case.
There is the general issue of not being able to easily filter your exceptions and act on them based on type. However, i don't know if there is a C++ specific reason not to do it
If your idea of throwing a string as an error was for convenience of showing the error to the user, consider that this would make localizing your application more difficult (may or may not be a concern to you though).
Also if another part of the application needs to understand what the error is so it can react to it (eg if it is a disconnect error, try to reconnect automatically, but if it's a password error, just show error message to the user), it is better to have some sort of error code available to the exception catcher.
In our app, our exceptions are derived from std::exception. They contain an error type (an enum), a debug error message (including file/line number), and a localized error string.
Throwing a string literal is generally a bad idea because, as the code evolves, programmers may need to enrich the error message with some more information, e.g. the value of a variable, or the line number from which the exception is thrown.
Given unknown client code that's catching const char*
, the programmer's encouraged to use a more dynamic mechanism to concatenate desired information:
std::string
and +
std::ostringstream
strcat
and/or sprintf()
The most obvious ways of using these don't work or don't work well:
// temporaries...
throw (std::string("couldn't parse input: ") + input).c_str();
throw (std::ostringstream() << "error line " << __LINE__).str().c_str();
char buf[1024]; sprintf(buf, "error line %ld%", __LINE); throw buf;
// not thread-safe
static char buf...
Even if the programmer knows not to do any of these, they'll still have a right time finding all the client code that needs to start accepting a richer value type, especially if other throw
/catch
usage of const char*
persists.
So, using a class that embeds a flexible std::string
description by value is very important for writing maintainable code.
No there is problem with throwing a char
array. Just that you should receive as,
catch(const char* const errorMessage) {...}
1st const
is to add ability to receive any char
array char*
const char*
char[]
const char[]
2nd const
is to specify that errorMessage
is not intended to change within catch
block
I think this is much more simpler. :).
#include <iostream>
#include <exception>
using namespace std;
int main() {
try {
throw runtime_error("This is an Error");
}catch (exception& e){
cout << "Exception: " << e.what() << endl;
}
return 0;
}