Recovering from errors

Hi, I'm a beginner in programming and I'm studying the C++ programming language using the book : Programming principles and practice using C++ . I'm here today because I need help with a fragment of code in chapter 7, in this chapter the author shows to the reader how to complete a program (the authors uses a calculator program as example) and now he is trying to teach me how to recover from an error instead of just throwing an exception and ending a program using the try-catch block .

Here is the code wich I can't properly understand (I don't post all the code because what I don't understand is just a loop which uses exception)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "std_lib_facilites.h"



const string prompt = ">"; 
const string result = "="; 
const string quit = "q"; 

void calculate()
{
	 while (cin)
	 try {
 		cout << prompt; 
 		Token t = ts.get(); 
		while (t.kind == print) t = ts.get(); 
	        if (t.kind == quit) return; 
		ts.putback(t);
	       cout << result << expression() << '\n'; 
       }
	catch (exception& e) {
		cerr << e.what() << '\n'; 
	clean_up_mess(); 
	}
    }


int main()
try {
	calculate(); // execute the calculation loop
	keep_window_open(); // for some windows configuration
	return 0; 

}
catch (runtime_error& e) {
	cerr << e.what() << '\n'; 
	keep_window_open(); 
	return 1; 
}
catch (...) {
	cerr << "exception\n";
	keep_window_open(); 
	return 2; 
}


Why after the try-block catches an exception in the while loop of the calculate() function, instead of restarting the loop ? I thought that once catched an exception the program would be restarted from the main() function .
Last edited on
In Common Lisp, you have so called restarts and conditions; this is what you're thinking of and looking for.

Exceptions, however, are not working like this.

One of the reasons is that when exception is thrown, you leave the scope up to try/catch block, causing stack unwinding; so whatever was the reason of error, you probably lost your chance to fix it.

Anyway, you usually don't use exceptions to "fix" errors(mostly), because of many factors that can cause code to fail. Rather you do whatever you need to make sure that error is either signalled to user before application exits, or that error doesn't impact application's workflow(too much).
Most of the time, you simply assume that either error is so serious, that you can't(or don't want to) recover from it, so you signal error and quit, or you try to make application work without the code that raised an exception; alternatively, you try to fix an error, and call the code that thrown an exception again.

In code above(function calculate), you try to parse something, and if you don't succeed for some reason(e.g. malformed input), you know that code can throw an error; therefore you catch it(you assume type of thrown exception will be std::exception), print it to cerr, and "clean_up_mess".

In main, you call calculate and keep_window_open. In there, we assume that either of these can throw an error (notice that, from code of calculate, you know that only way that calculate would throw anything would be clean_up_mess throwing another exception, because calculate itself catches an error and does not "rethrow" it). If an exception of type std::runtime_error is thrown, it'll be caught in first catch. If it's of any other type, it'll be caught in second catch.

Exceptions doesn't "restart" anything. You go to proper catch(if any) block, fill it, and continue code. No restarting main function.
Last edited on
I did not quite get your question.
Once you catch an exception and handle it, program will resume execution of the next statemet of the try-catch block. In your cas it is:
1
2
3
4
while(cin) {
    <try-catch block>
    //←Execution is resumed here
} 
So it is logical that loop will be restarted, condition checked, etc...
IMO, exceptions are overkill for editing user input. It is much simpler to have an edit function which returns true or false depending on whether the input is good. The edit routine can be as simple or as fancy as you want or need. No try/catch blocks needed. No need for any fancy cleanup.

Exceptions can be very useful for handling unexpected error conditions. However, bad input from the user is not an unexpected error condition.
Topic archived. No new replies allowed.