Reputation: 3246
I was told in a comment in another thread that I should be using exceptions whenever anything out of the ordinary happens, even if it isn't fatal to the script. This came up as I was using constructs akin to the following:
return err("File could not be loaded");
which would print the error to the screen, and return false, terminating the instruction processing. It was suggested that this would be better handled with exceptions.
The trouble is that the program is, for all intents and purposes, a language interpreter, controlled through a console, which means that any time a command is input incorrectly, or there is a bug in the interpreted code, an error needs to be displayed.
Besides the fact that these issues seem to minor to be processed as exceptions, how should it be implemented? How can a try block be used to control processing paths? For example, currently my code looks as follows:
if(!validate(code))
return false; //the validate function already having output the error
else
process(code);
How should I ensure that process(code) only executes if validate(code) succeeds? Should I just return false;
from the function in the catch block? This would seem to return to the original issue of using return values to handle exceptional events. It seems to me that the fundamental problem is that the issues aren't exceptions at all, but I defer to those with more experience than I.
Upvotes: 1
Views: 1470
Reputation: 264689
There is no one correct answer.
It is highly dependent on the code and the situation:
In your situation the simple code above (if it is withing my own class) then error codes are fine:
class MyClass
{
public:
void processesValidCodesOrIgnore(int code)
{
if (validate(code))
{
processesCode(code);
}
}
private:
bool validate(int);
void processesCode(int);
};
As the validate method is private I know its result will always be checked and not ignored so its very easy to just use error codes in this situation.
On the other hand if validate was public I would definately consider using exceptions (depending on usage). As this would force the caller to actively check for problems rather than silently ignoring them.
Upvotes: 0
Reputation: 82555
Maybe you want your top-level loop to look something like this:
while (!quit) {
try {
process_command_line_input();
}
catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}
}
So, process_command_line_input()
gets the next line of input and does whatever it does. If any error is detected, an exception is thrown, the top level loop displays it, and then goes on to the next input line.
Upvotes: 2
Reputation: 72319
If an operation may - by design - either succeed or fail, and both of those are common, it might be most clear to structure your command flow in such way that errors are checked "explicitly", like in boolean value of "validate" function.
Exceptions come in handy when you don't want to disturb your regular control flow with error checking and want to move the checking somewhere else, maybe some function call levels above.
Your situation sounds like you don't really need exceptions. If your code looks clean without them, stay with it.
Upvotes: 4
Reputation: 106609
The idea of exceptions is you wouldn't need something like a separate "validate" step. Whenever "process" gets to a point where something's broken, throw an exception.
If you did need a separate validation step for some reason, then it'd look like
validate(code);
process(code);
Validate would throw an exception on failure, in which case process would never be reached.
Upvotes: 3
Reputation: 147036
The issue is that you have your function set up to use a return code. You can't just drag and drop exceptions in when your code is already set up with return values.
The correct way to do it is like
std::string code;
// input into code
try {
validate(code);
process(code); // Throws an exception.
}
catch(std::runtime_error& except) {
std::cout << except.what();
// recover from here.
}
Upvotes: 1
Reputation: 40897
try
{
validate(code);
process(code);
}
catch(...)
{
return false;
}
return true;
Assuming that validate
throws, process
won't happen.
Upvotes: 2