# 6 Tuning the Example

Raising Exceptions

In line 10 the program simply returns `OZ_FAILED` if the environment variable is not defined, which is not good programming style. It should better raise an exception. This can be done using

> `OZ_Return OZ_raise(OZ_Term t);`

which raises the exception `t`. In our example we should replace line 10 with something like

> `return OZ_raise(OZ_atom("envVarNotDefined"));`

We leave as an exercise to the reader to give more informative exception, e. g. adding the name of the undefined variable.

Raising type errors

Furthermore an extra function is provided for raising type errors. The macro `OZ_declareAtom` used in our example makes use of this function. Type errors can be signaled using

> `OZ_Return OZ_typeError(int pos, char *expectedType);`

This is an exception signaling that the argument at position `pos` is incorrect and the name of the expected type is `expectedType`.

Suspension of C functions

The macro `OZ_declareAtom` internally also makes use of facilities that allow C functions to suspend the running thread on variables. Thus `OZ_declareAtom` uses some code of the following form:

> `if (OZ_isVariable(envVarName)) {
> OZ_suspendOn(envVarName);
> }`

If `envVarName` is an unconstrained variable then `OZ_suspendOn` is called. `OZ_suspendOn` is a macro that takes a variable as argument and suspends the current thread. If the variable is determined the suspended thread becomes runnable in which case it will reexecute the C function from the beginning.

The application

> `declare X in {Browse {Goodies.getenv X}}`

will call the C function as above. But the first argument is detected as variable and the executing thread suspends.

If we feed

> `X='HOME'`

the C function `BIgetenv` is called again from the beginning and the browser updates the display of the value of the environment variable as expected.