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.
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/ |
Library File Documentation | Description |
---|---|
ajmess | Message handling |
ajexcept | Internal exception handling functions |
ajassert | Functions for handling assertions |
ajmess.h/c
. Defines 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/c
. Contains the ajExceptRaise
function for raising an exception.
ajassert.h/c
. Contains 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.
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.
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.
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);
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);
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); }