6.23. Handling Exception Messages

6.23.1. Introduction

EMBOSS provides a set of useful exception handling functions which format an exception message before calling a function to output the message. The following behaviours are available:

  • Call the registered exception handling function (see below).

  • Report an informative message

  • Report a warning message

  • Report an error message

  • Dump diagnostic data

  • Exit

  • Crash (kill) the application

  • Debug

The most widely used are the functions ajFatal (crash the application), ajWarn (warning message) and ajDebug (debug) (see Section 3.3, “Debugging”).

In rare cases it is desirable to write your own customised exception handling functions and functions are provided for this. There are also functions to query or set the internal status of message handling. You will not normally need these but they might come in useful when writing your own exception handling code.

6.23.2. AJAX Library Files

AJAX library files for handling messages are listed in the table (Table 6.38, “AJAX Library Files for Handling Messages”). Library file documentation, including a complete description of datatypes and functions, is available at:

http://emboss.open-bio.org/rel/dev/libs/
Table 6.38. AJAX Library Files for Handling Messages
Library File DocumentationDescription
ajmessMessage handling
ajexceptInternal exception handling functions
ajassertFunctions for handling assertions

ajmess.h/cDefines the error message object (AjPError) and functions for message handling. It also contains static data structures and functions for handling messages at a low level. You are unlikely to need the static datatypes and functions unless you plan to extend the core library functionality.

ajexcept.h/cContains the ajExceptRaise function for raising an exception.

ajassert.h/cContains functions for handling assertions. The smplest use is to add a line:

  AjPStr mystring = NULL;

  /* ... some code ... */

  assert(mystring);

this will raise a fatal exception when mystring has a NULL value.

6.23.3. ACD Datatypes

There are no ACD datatypes dedicated for messages.

6.23.4. AJAX Datatypes for Handling Messages

For handling messages use:

AjPError

Error message level information.

These are used internally. For handling exceptions define an Except_T with a text description, and use the AJRAISE macro to report the text string, and the name and line number of the source file. The exception handling datatypes are:

Except_T

Types of exceptions.

Except_Frame

Used for the exception stack.

For all intents and purposes you will not need to handle these objects directly.

6.23.5. Message Functions

Functions to format messages (provided as a string) all have convenient wrapper functions with short memorable names:

void  ajDebug (const char *fmt, ...);
void  ajDie (const char *format, ...);
void  ajErr (const char *format, ...) ;
void  ajUser (const char *format, ...) ;
void  ajWarn (const char *format, ...);
void  ajMessDump (const char *format, ...);
void  ajMessExitmsg(const char *format, ...);

All these functions call message output functions that are internally defined.

The functions are invoked with the message text, for example:

    ajWarn("This is a silly warning message");

The call can of course include variables to print:

    ajint x=0;
    ...
    ajWarn("This is a silly warning message which prints integer value %d", x);

ajDebug will write a debug message to the debug file if debugging has been turned on. Debugging is typically turned on by adding -debug to the command line or by defining the environment variable EMBOSS_DEBUG. You should avoid using ajDebug in any code which might be called before command line processing completes as the debug file has not yet been created

ajMessExitmsg does not give an opportunity to output logged error messages before exiting, but is useful for handling errors that, while being unrecoverable, are not a problem with the EMBOSS code itself.

6.23.6. Querying the Status of Message Handling

A few functions are provided to query the internal status of message handling. These have the prefix ajMessGet. For example the number of times the error routines have been called, the current message text, the system error message text from the standard C function strerror or the file used for debug output can all be retrieved:

ajint  ajMessGetCountError (void);
const char*  ajMessGetMessageC (void);
const char*  ajMessGetSysmessageC (void);
FILE*  ajMessGetDebugfile (void);

6.23.7. Interacting with the user

One function is used for all user prompting in the initialisation on an EMBOSS application. ajUserGet writes a prompt to the user and reads a one line response. ajMessBeep generates an audible warning:

ajint  ajUserGet (AjPStr* pthis, const char* fmt, ...);
void  ajMessBeep (void);

6.23.8. Miscellaneous functions

To raise an exception manually ajExceptRaise (defined in ajexcept.h/c) may be used. The function is available as a macro called (AJRAISE):

__noreturn void  ajExceptRaise(const T* e, const char* file, ajint line);

#define AJRAISE(e) ajExceptRaise(&(e), __FILE__, __LINE__)

It will check for an exception and call the registered exception routine if one is caught. Otherwise it will raise an exception message with the file name of the source code and code line number before aborting the program.

The macro version should always be used. For example:

static const Except_T Mem_Failed =
{
    "Allocation failed, insufficient memory available"
};

static const Except_T Mem_Badcount =
{
    "Allocation bad byte count"
};

/* Allocates memory using malloc, and fails with an error message if unsuccessful.
   nbytes : number of bytes required
   file   : source file name (generated by macro)
   line   : source line number (generated by a macro)

void *ajMemAlloc(size_t nbytes, const char* file, ajint line)
{
    void *ptr;

    if(nbytes <= 0)
        ajExceptRaise(&Mem_Badcount, file, line);

    ptr = malloc(nbytes);

    if(ptr == NULL)
    {
        if(file == NULL)
            AJRAISE(Mem_Failed);
        else
           ajExceptRaise(&Mem_Failed, file, line);
    }