Error Handling in Scripts

The Photo>Graphics Pro scripting interface handles errors in way that is different from the traditional REXX approach.

On most REXX-based scripting systems, error information is returned by means of an error code.

Every function returns a code to indicate whether or not it was able to complete successfully. If a Photo>Graphics-specific error occurs (e.g. unable to load a file), a syntax error condition is raised and the error message can be retrieved by calling CwGetErrorMsg. Thus, the default way for a Photo>Graphics PRO procedure to handle an error is to stop the script and display a diagnostic error message.

If you wish your script to recover from such an error, you must use SIGNAL to do so and then call CwErrorMsg to retrieve the error message. (If no error occurred, CwErrorMsg will return an empty string. This means you can easily separate the Photo>Graphics PRO run-time errors from the real syntax errors.)

Here's the reasoning behind this policy: REXX scripts will usually be used for automation of mundane things--quick and dirty utilities. However, it is occasionally necessary to do something more complicated in REXX. Those sorts of tasks should still be possible and the quick-and-dirty stuff should be easy. It also ensures that a failing script will not accidentally continue, possibly ruining some great work of art!

For example:

call CwImportProject projectFile
is preferable to
rc = CwImportProject(projectFile)
if rc = 0 then do
  Say "Error.  Unable to open file" projectFile
  exit
  end
Normally, if you try a quick & dirty script, you tend to ignore return values. Consider the following:
...
x=CwImportProject(pf)
oh=CwGetHandleFromObjectName('foo')
x=CwSetProperty(oh,"position:x", 5)
...

In this case, if the variable pf contains an invalid filename, the script will simply fail silently and it's up to the user to add debugging SAYs. That can be a lot of work. Under the Photo>Graphics PRO error handling system, a bogus filename causes the script to stop and a meaningful error message to be displayed (along with line-number) in a message box. The error is easy to track down.

If you wish to write a more complex script (one that is robust), it is possible to recover from errors, although it requires a bit more work. However, a script complex enough to require that level of robustness will already be pretty long, so it's no big loss.

Trapping fatal errors is quite easy. Just do the following:

  1. Trap all errors using the SIGNAL command.
  2. Make the dangerous function calls.
  3. If successful, disable trapping and continue.
  4. In the error handler section:
    1. Disable trapping.
    2. Use CwGetErrorMsg and/or CwGetErrorFun to determine if there is an error message. If not, the error did not occur in Photo>Graphics PRO, there was a real syntax error and you will need to fix the bug. Exit.
    3. Clear the error message with CwClearError. (Otherwise, the error message will remain, causing a subsequent legitimate syntax error to be treated as a Photo>Graphics PRO error, with no end of problems resulting.)
    4. Do whatever is supposed to be done in the event of an error.

Here's an example. This is a function that attempts to load a project and returns 1 to indicate success and 0 to indicate failure:

loadFile:procedure
parse arg projectFile

signal on syntax name cantload  /* Trap syntax errors.*/
call CwImportProject projectFile

/* Success.  Switch trapping off and return. */
signal off syntax
return 1

/* Failure.*/
cantload:
signal off syntax

/* Check if the error isn't really something in the REXX end. */
msg = CwGetErrorMsg()
if msg = '' then do
  say "REXX syntax error."
  exit
  end
else do
  /* OK, it's ours.  Print an error message, clean up and return.*/
  say 'Error: ' msg 'in' CwGetErrorFun()
  call CwClearError
  end
return 0


Data Types

Index

Running Scripts