6.3. Error Handling - interactive session

The code below provides an example of starting an interactive session in case of an error. In this example a window with two buttons is created. Pressing the button labeled good button will print a message to stdout. Pressing the button labeled error button will cause the UNDEFINED symbol g to be evaluated. This causes an error and starts the interactive session from the catch block. The function that runs the interactive session is designed to be recursive and relies on the dynamic scoping of variables in Gamma. Notice that Lisp grammar is being used in this interactive session. You can query the value of any variable simply by typing the variable name in. For example:

win
but1
but2
(@ win title)
	  

or use some functions like:

(stack)
(* 8 3)
	

Before terminating the interactive session, try to resize the window. Notice that it does not work because the event loop is temporarily suspended. Now exit the interactive session by typing Ctrl - D and notice that the window can now be resized. Also notice that once the event loop is re-started, the contents of the window are not updated but the callbacks are still active. This happens because Photon was interrupted in the middle of a function call and an error condition now exists between Gamma and the Photon library.

#!/usr/cogent/bin/gamma

require_lisp("PhotonWidgets");

PtInit(nil);
win = new(PtWindow);
win.SetArea(100,100,100,100);

but1 = new(PtButton);
but1.text_string = "good button";
PtAttachCallback(but1,Pt_CB_ACTIVATE,#princ("good button\n"));
but1.SetPos(10,10);

but2 = new(PtButton);
but2.text_string = "error button";
PtAttachCallback(but2,Pt_CB_ACTIVATE,#g);
but2.SetPos(10,40);

PtRealizeWidget(win);

function interactive_mode ( level )
{
	local expr;
	
    princ("internal error: ", _last_error_,"\n");
    writec(stdout,"\ndebug", level,">");
    while ( (expr = read(stdin)) != _eof_)
	{
        try
        {
            writec(stdout,eval(expr));
            writec(stdout,"\ndebug", level,">");
        }
        catch
        {
            interactive_mode(level + 1);
            writec(stdout,"\ndebug", level,">");
        }
    }   
}

while (t)
{
    try
    {
        next_event();
    }
    catch
    {
        princ("starting temporary interactive mode using Lisp grammar\n");
        princ("use ^D to exit this mode and return to event loop\n");
        interactive_mode(1);
        princ("\nleaving temporary interactive mode\n");
    }
}