Up: Classes   [Index]


Exception

Exception Class

Exception and its subclasses handle system and language errors. These classes provide default and user-defined handlers to respond to the Exceptions;

If a program calls enableExceptionTrace (class Object), then the handle method, below, and other exception handlers print a walkback of the program’s method stack. See Object.

Here is an example of how to handle an exception when trying to open a file.

Exception new e;
...
e enableExceptionTrace;
...
inputStream openOn fileArg;
if (e pending) {
  e handle;
  exit (1);
}

The pending method returns TRUE or FALSE depending on whether an exception is waiting to be processed. The handle method processes the exception.

The class’s default method handlers format and print the text provided when a program calls raiseException. Here is the code from openOn (class ReadFileStream) that creates the exception.

SystemErrnoException new e;
...
if ((f = fopen (__streamPath, "r")) != NULL) {
  __ctalkObjValPtr (selfval, f);
  self streamPath = __streamPath;
  self statStream;
} else {
  e raiseCriticalException __streamPath;
  strcpy (selfval -> __o_value, "");
}

The object e is a SystemErrnoException. The SystemErrnoException class translates the operating system’s errors into Ctalk exceptions. In the example above, the type of the exception is provided by the operating system.

The Exception class also provides the installHandler method to allow programs to use their own handlers. Here is an example.

Exception instanceMethod myHandler (void) {
  printf ("My exception handler: %s.\n",
	  __ctalkGetRunTimeException ());
  return NULL;
}

int main () {
  Exception new e;
  e installHandler "myHandler";
  e raiseException USER_EXCEPTION_X, "my program's exception";
  e handle;
}

Some notes about exceptions:

1. The receiver class of an exception handler is the the same as the exception object; e.g., myHandler in the example above is the same as the class of e; that is, Exception. In addition, exception handlers take no arguments and rely on information at the time the exception is raised.

2. Programs must take care that they handle any exceptions that they raise as soon as possible. If not handled by the application, the run-time library API might then handle the exception, which could lead to confusing results.

3. Ctalk uses critical exceptions internally. At the application level, however, all exceptions are treated with the same priority. The application needs to take the appropriate action, depending on the type of exception.

4. Exception classes should not, as much as possible, depend on other classes being evaluated. This is because even basic classes use exceptions, and if the exceptions in turn use the basic classes, it can lead to circular reference. In fact, Symbol is one of the few classes that Exception can use without generating circular method and class references. That is why the handlerMethod instance variable (see below) is implmented as a Symbol.

5. When writing exception handlers, you should use as much as possible the following library API functions: __ctalkGetRunTimeException, __ctalkHandleRunTimeException, __ctalkPeekRunTimeException, __ctalkPeekExceptionTrace, and __ctalkPendingException. They are located in lib/except.c and described in a later section. See Ctalk library.

6. The only way to distinguish between different exceptions within a handler is to compare the text returned by a function like __ctalkGetRunTimeException. The exception information is generated at the time the exception is raised, which is the information that the program should be interested in. Handling exceptions as soon as possible also helps avoid confusion if one exception then causes other exceptions. Also, different operating systems map errors codes differently, so Ctalk uses the operating systems’ interpretations of the errors.

7. Exception handlers in calling methods take priority over handlers in the methods they call. You need to be careful that exception handlers within the scope of a caller do not supercede each other. This is especially true if an application tries to use a global Exception object. You should try to keep Exception objects as local as possible.

Exception Codes

Exceptions have a corresponding integer code. The following macros correspond to the actual exceptions.

SUCCESS_X
CPLUSPLUS_HEADER_X
MISMATCHED_PAREN_X
FALSE_ASSERTION_X
FILE_IS_DIRECTORY_X
FILE_ALREADY_OPEN_X
UNDEFINED_PARAM_CLASS_X
PARSE_ERROR_X
INVALID_OPERAND_X
PTR_CONVERSION_X
UNDEFINED_CLASS_X
UNDEFINED_METHOD_X
METHOD_USED_BEFORE_DEFINE_X
SELF_WITHOUT_RECEIVER_X
UNDEFINED_LABEL_X
UNDEFINED_TYPE_X
UNDEFINED_RECEIVER_X
UNKNOWN_FILE_MODE_X
INVALID_VARIABLE_DECLARATION_X
WRONG_NUMBER_OF_ARGUMENTS_X
SIGNAL_EVENT_X
INVALID_RECEIVER_X
NOT_A_TTY_X
USER_EXCEPTION_X

Instance Variables

handlerMethod

A Symbol object that contains the address of a user defined method to handle exceptions.

Instance Methods

deleteLastException (void)

Delete the last generated exception from Ctalk’s internal exception list.

handle (void)

Execute the exception handler for the next pending method. If a program calls enableExceptionTrace (class Object), then handle also displays a walkback of the exception’s copy of the program call stack. See Object.

exceptionHandler (void)

Handle an exception either with Ctalk’s default exception handler or a user defined handler. If the program has called the traceEnabled method (class Object), print a stack trace also.

installHandler (char *handler_method_name)

Install a user-defined method to handle exceptions. The method’s receiver class must be of the same class as the exception; i.e., either Exception or SystemErrnoException.

peek (void)

Returns a String containing the text of the first pending exception, if any.

pending (void)

Return TRUE if any exceptions are pending, FALSE otherwise.

raiseCriticalException (EXCEPTION ex, char *text)

Raise a critical exception. A critical exception is similar to a normal exception, below, except that it is not caught internally. The application must catch the exception with pending and handle.

You should use one of the EXCEPTION macros defined above as the argument ex.

Print a trace of the methods in the current exception’s copy of the program’s call stack.

raiseException (EXCEPTION ex, char *text)

Raise an exception. You should use one of the EXCEPTION macros defined above as the argument ex.


Up: Classes   [Index]