开发者

c++ non-fatal exception handling

开发者 https://www.devze.com 2023-01-30 14:49 出处:网络
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

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 l开发者_开发技巧anguage 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.


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.


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.


try
{
  validate(code);
  process(code);
} 
catch(...)
{
  return false;
}
return true;

Assuming that validate throws, process won't happen.


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.


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.
}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号