Termination, Error Handling and Progress Feedback

With normal execution of a GX, no explicit termination statement is required. The process proceeds to the last executed statement in the main program block. A number of cases exist, however, perhaps due to errors in execution, unexpected parameter values, or user intervention, when the GX must terminate prematurely. Several functions exist to handle the various scenarios.


 

Exit_SYS Function

The Exit_SYS function is a “soft landing” early exit. Execution ceases as if it were the end of the GX, and no message is written to the user or log file. No error is registered, so if the GX has been called from another GX, the calling GX will proceed normally.

Cancel_SYS Function

The Cancel_SYS function is normally used in response to a user selecting the “Cancel” (or corner “X” button) in a dialog. No message is output, and, if this GX is called from another GX a value of 1 will be returned to the calling GX, which should be handled as necessary (See Calling GXs from within a GX below), usually with its own call to Cancel_SYS.

Abort_SYS Function

The Abort_SYS function terminates the GX with a message. It is normally used in the non-interactive section of a GX when a bad or missing parameter is detected, and the GX may not safely continue. A call to Abort_SYS terminates not only the current GX, but any GXs which happen to have called the current GX.

Messages and Warnings to Users

Within interactive sections of the GX it is possible, through careful design, to “trap” bad or missing parameter values, or unusual conditions, and alert the user, without terminating the GX with a call to one of the above three functions. One method is to enclose the interactive portion of the GX within a while(){} statement, and break out of the loop only when all necessary conditions have been met. A DisplayMessage_SYS (or DisplayInt_SYS or DisplayReal_SYS) message can be used to alert the user. Once the user reads the message and selects the “Ok” button, the dialog comes up again so the value can be altered. The following is an example:

if(iInteractive_SYS()) {
   iDone = 0;
   while(iDone!=1) {
 
// --- Do dialog stuff here ...
      .
      .
      .
 
// --- Retrieve and validate a variable ---
 
      GetReal_SYS("MYGX","MYPARAM",rVal);
 
      if(rVal<=0.0)
		DisplayMessage_SYS("Bad value: MYPARAM", "Must be > 0.0");
      else
		iDone = 1;   // A “break;” statement would also work
   }
}

Progress Indicators

For processes that may take a long time to complete, it is important to provide feedback to the user about the current state of progress. The Progress_SYS functions are designed to create a progress bar with a message and “Stop” button to allow premature termination of the process. The following example illustrates the various aspects of setting up a progress indicator:

The progress bar shows the percentage of the process which has been completed. To calculate the percentage requires that some progress variable be defined. Often, this is the number of selected lines in a multi-line database. Alternatively, it could be the number of rows in a single line of data.

iLines = 0;
iTotLines = iCountSelLines_DB(Data);

Turn on the progress indicators. Many Geosoft functions contain their own progress reporting capabilities, which are normally disabled. Calling Progress_SYS(1) activates not only the progress indicators for the current GX, but for the called functions as well.

Progress_SYS(1);

Set a progress name. This may be done once, or may be changed on each update of the progress indicator. In this case it will be changed with every line. This call, without a name, is used to set the initial indicated percentage to 0.

ProgName_SYS("",1);

Update the progress bar within the process loop. The message is changed to reflected the current line, without affecting the displayed percentage. The iCheckStop_SYS function allow the user to break prematurely from the process.

// --- Go through all selected Lines ---
 
Line = FirstSelLine_DB(Data);
while (iIsLineValid_DB(Data,Line))
{
   // --- Update the Progress Bar ---
 
   LockSymb_DB(Data,Line,DB_LOCK_READONLY,DB_WAIT_INFINITY);
   GetSymbName_DB(Data,Line,sTemp);
   UnLockSymb_DB(Data,Line);
   Strcpy_STR(sLabel, "Copy line: ");
   Strcat_STR(sLabel,sTemp);
   ProgName_SYS(sLabel,0);
   ProgUpdate_SYS( (int) ((real) iLines / (real) iTotLines * 100.0));
 
   // --- Allow user a premature exit ---
   if(iCheckStop_SYS()) Cancel_SYS();
 
   // --- Do processing ...
   .
   .
   .
 
   // --- Advance to the next line ---       
 
   Line = NextSelLine_DB(Data, Line );
   iLines++;      // increment a counter for the progress bar
}
 
// --- Set the progress indicator to 100% --- 
ProgUpdate_SYS(100.0);

 Finally, after all processing function calls, turn off the progress indicator

Progress_SYS(0);