Next Previous Contents

## 3. Error Handling

Many of the S-Lang functions return 0 upon success or -1 to signify failure. Other functions may return `NULL` to indicate failure. In addition, upon failure, many will set the error state of the library to a value that indicates the nature of the error. The value of this state may be queried via the `SLang_get_error` function. This function will return 0 to indicate that there is no error, or a non-zero value such as one of the following constants:

> `

>          SL_Any_Error                      SL_Index_Error
>          SL_OS_Error                       SL_Parse_Error
>          SL_Malloc_Error                   SL_Syntax_Error
>          SL_IO_Error                       SL_DuplicateDefinition_Error
>          SL_Write_Error                    SL_UndefinedName_Error
>          SL_Read_Error                     SL_Usage_Error
>          SL_Open_Error                     SL_Application_Error
>          SL_RunTime_Error                  SL_Internal_Error
>          SL_InvalidParm_Error              SL_NotImplemented_Error
>          SL_TypeMismatch_Error             SL_LimitExceeded_Error
>          SL_UserBreak_Error                SL_Forbidden_Error
>          SL_Stack_Error                    SL_Math_Error
>          SL_StackOverflow_Error            SL_DivideByZero_Error
>          SL_StackUnderflow_Error           SL_ArithOverflow_Error
>          SL_ReadOnly_Error                 SL_ArithUnderflow_Error
>          SL_VariableUninitialized_Error    SL_Domain_Error
>          SL_NumArgs_Error                  SL_Data_Error
>          SL_Unknown_Error                  SL_Unicode_Error
>          SL_Import_Error                   SL_InvalidUTF8_Error

> `

For example, if a function tries to allocate memory but fails, then `SLang_get_error` will return `SL_Malloc_Error`.

If the application makes use of the interpreter, then it is important that application-specific functions called from the interpreter set the error state of the library in order for exception handling to work. This may be accomplished using the `SLang_set_error` function, e.g.,

> `

>          if (NULL == (fp = fopen (file, "r")))
>            SLang_set_error (SL_Open_Error);

> `

Often it is desirable to give error message that contains more information about the error. The `SLang_verror` function may be used for this purpose:

> `

>          if (NULL == (fp = fopen (file, "r")))
>            SLang_verror (SL_Open_Error, "Failed to open %s: errno=%d",
>                          file, errno);

> `

By default, `SLang_verror` will write the error message to `stderr`. For applications that make use of the SLsmg routines it is probably better for the error message to be printed to a specific area of the display. The `SLang_Error_Hook` variable may be used to redirect error messages to an application defined function, e.g.,

> `

>          static void write_error (char *err)
>          {
>             SLsmg_gotorc (0, 0);
>             SLsmg_set_color (ERROR_COLOR);
>             SLsmg_write_string (err);
>          }
>          int main (int argc, char **argv)
>          {
>             /* Redirect error messages to write_error */
>             SLang_Error_Hook = write_error;
>                   .
>                   .
>          }

> `

Under extremely rare circumstances the library will call the C `exit` function causing the application to exit. This will happen if the `SLtt_get_terminfo` is called but the terminal is not sufficiently powerful. If this behavior is undesirable, then another function exists (`SLtt_initialize`) that returns an error code. The other times the library will exit are when the interpreter is called upon to do something but has not been properly initialized by the application. Such a condition is regarded as misuse of the libary and should be caught by routine testing of the application during development. In any case, when the library does call the exit function, it will call an application-defined exit hook specified by the SLang_Exit_Error_Hook variable:

> `

>          static int exit_error_hook (char *fmt, va_list ap)
>          {
>             fprintf (stderr, "Fatal Error.  Reason:");
>             vfprintf (stderr, fmt, va_list);
>          }
>          int main (int argc, char **argv)
>          {
>             SLang_Exit_Error_Hook = exit_error_hook;
>               .
>               .
>          }

> `

The idea is that the hook can be used to perform some cleanup, free resources, and other tasks that the application needs to do for a clean exit.

Next Previous Contents