Error: Extensible error handling.
[Query Object Framework]

Detailed Description

QofError supports the creation of new error codes (complete with error strings) along the lines of GdaError. Applications and backends can generate their own QofError values and register them with QofError. Any function can then set this error value and retrieve the error with qof_error_get_id or qof_error_get_message. The main advantage is that applications can set error states that are unrelated to the old QofBackendError values but retrieve all errors in the same manner.

An error must be registered to be set. Registered errors can be set repeatedly into an error stack for the relevant session. Setting an error copies the registered error to the error stack and sets a time index in the copy.

Once an error has been unregistered, it cannot be set later. If the error has already been set on the error stack, the stack is not changed and the error remains readable.

Each error stack is specific to one QofSession.

Registered errors can be set in any session (if the QofErrorId is known) but most errors are specific to one session.

Applications can register new error values with qof_error_register passing the error message string, already marked for translation - a new QofErrorId will be returned. Error values are unregistered when the session ends or can be unregistered manually.

Each backend can also generate specific QofError values, in which case the translation is done within QOF.

Set an error by passing the QofErrorId (or the deprecated QofBackendError) to qof_error_set.

To check the error condition use qof_error_check - if an error has been set, qof_error_check returns the QofErrorId of that error without clearing the error from the stack.

To retrieve an error and clear it from the stack, use qof_error_get_id or qof_error_get_message.

Precise values of QofErrorId are not to be stored in applications as values (other than deprecated values) may change at any time.

There are no default errors - previous QofBackendError values are retained only as deprecated macros. Until libqof2, QofErrorId is guaranteed not to overlap a previous QofBackendError value but once deprecated code is removed in libqof2, any value can be used.

This deliberately makes it harder to re-use the same error time after time. The purpose is to encourage more detailed error reporting by supporting an unlimited number of error values.

Applications and backends can store the QofErrorId in a context or static values if the error must be set from multiple locations, otherwise an error can be registered and set locally.

If a subsystem or dependency generates an error message of it's own, this can also be passed to qof_error_register to generate a new error within the session, complete with the (translated) message direct from the subsystem. This increases the detail and clarity of the messages presented to the user. Programming errors and complex errors should still be logged using QofLog - QofError is for messages destined for the end user of the application using QOF.

Many applications already include message strings for the previous QofBackendError values but all are welcome to move to the new QofError strings.

QofError strings remain the property of QofError and should not be freed.



file  qoferror.h
 Extensible error handling.


#define QOF_MOD_ERROR   "qof-error-module"
#define QOF_SUCCESS   0
#define QOF_FATAL   -1
 general error value


typedef struct QofError_s QofError


QofErrorId qof_error_register (const gchar *err_message, gboolean use_file)
 Generate and register a new error.
void qof_error_unregister (QofErrorId id)
 Unregister an error.
void qof_error_set (QofSession *session, QofErrorId error)
 Add an error to the stack for this session.
void qof_error_set_be (QofBackend *be, QofErrorId error)
void qof_error_clear (QofSession *session)
 clear the error stack for the session.
QofErrorId qof_error_check_be (QofBackend *be)
 Check for errors.
QofErrorId qof_error_check (QofSession *session)
QofTimeqof_error_get_time_be (QofBackend *be)
 Get the time of the most recent error.
QofTimeqof_error_get_time (QofSession *session)
 Alternative for applications.
QofErrorId qof_error_get_id_be (QofBackend *be)
 Pop the most recent error from the backend stack.
QofErrorId qof_error_get_id (QofSession *session)
 Alternative for applications.
const gchar * qof_error_get_message_be (QofBackend *be)
 Pop the most recent error and get the message.
const gchar * qof_error_get_message (QofSession *session)
 Alternative for applications.

Define Documentation

#define QOF_FATAL   -1

general error value

Can be returned by any function handling QofErrorId to indicate a fatal error, e.g. g_return_val_if_fail

Definition at line 131 of file qoferror.h.

#define QOF_MOD_ERROR   "qof-error-module"

QofError log_module name.

Definition at line 121 of file qoferror.h.

#define QOF_SUCCESS   0

success value

Definition at line 124 of file qoferror.h.

Typedef Documentation

typedef struct QofError_s QofError

opaque QofError type.

Definition at line 118 of file qoferror.h.

Function Documentation

QofErrorId qof_error_check ( QofSession *  session  ) 

alternative for applications.

Definition at line 227 of file qoferror.c.

00228 {
00229     g_return_val_if_fail (session, QOF_FATAL);
00230     return qof_error_check_be (session->backend);
00231 }

QofErrorId qof_error_check_be ( QofBackend be  ) 

Check for errors.

be The backend to check.
QOF_SUCCESS if no errors have been set, otherwise the QofErrorId of the most recently set error.

Definition at line 234 of file qoferror.c.

00235 {
00236     QofError * qerr;
00237     GList * first;
00239     if (!be)
00240         return QOF_FATAL;
00241     if (g_list_length (be->error_stack) == 0)
00242         return QOF_SUCCESS;
00243     first = g_list_first (be->error_stack);
00244     qerr = (QofError*)first->data;
00245     if (!qerr)
00246         return QOF_FATAL;
00247     return qerr->id;
00248 }

void qof_error_clear ( QofSession *  session  ) 

clear the error stack for the session.

Applications should clear the stack once errors have been presented to the user.

Definition at line 209 of file qoferror.c.

00210 {
00211     g_return_if_fail (session);
00212     if (!session->backend)
00213         return;
00214     g_list_foreach (session->backend->error_stack, clear_list, NULL);
00215     g_list_free (session->backend->error_stack);
00216     session->backend->error_stack = NULL;
00217     if (session->error_message)
00218         g_free (session->error_message);
00219     session->error_message = NULL;
00220     session->last_err = QOF_SUCCESS;
00222     session->backend->last_err = QOF_SUCCESS;
00223 #endif
00224 }

QofErrorId qof_error_get_id_be ( QofBackend be  ) 

Pop the most recent error from the backend stack.

Returns and clears the most recently set error for this backend, if any.

be The Backend that recorded the error.
QOF_SUCCESS if no errors have been set, otherwise the QofErrorId of the most recently set error.

Definition at line 314 of file qoferror.c.

00315 {
00316     QofError * qerr;
00317     GList * first;
00319     if (!be)
00320         return QOF_FATAL;
00321     if (g_list_length (be->error_stack) == 0)
00322         return QOF_SUCCESS;
00323     first = g_list_first (be->error_stack);
00324     qerr = (QofError*)first->data;
00325     if (!qerr)
00326         return QOF_FATAL;
00327     be->error_stack = 
00328         g_list_remove (be->error_stack, qerr);
00330     set_previous_error (be);
00331 #endif
00332     return qerr->id;
00333 }

const gchar* qof_error_get_message_be ( QofBackend be  ) 

Pop the most recent error and get the message.

Clears the most recently set error for this backend and returns the error message, if any.

be The Backend that recorded the error.
NULL if no errors have been set, otherwise the translated message for the most recently set error.

Definition at line 364 of file qoferror.c.

00365 {
00366     QofError * qerr;
00367     GList * first;
00369     g_return_val_if_fail (be, NULL);
00370     if (g_list_length (be->error_stack) == 0)
00371     {
00372         DEBUG (" empty error stack");
00373         return NULL;
00374     }
00375     first = g_list_first (be->error_stack);
00376     qerr = (QofError*)first->data;
00377     if (!qerr)
00378     {
00379         DEBUG (" empty QofError value");
00380         return NULL;
00381     }
00382     DEBUG (" qerr->message=%s", qerr->message);
00383     be->error_stack = 
00384         g_list_remove (be->error_stack, qerr);
00386     be->error_msg = qerr->message;
00387     set_previous_error (be);
00388 #endif
00389     return qerr->message;
00390 }

QofTime* qof_error_get_time_be ( QofBackend be  ) 

Get the time of the most recent error.

All QofError values are timestamped at the moment that the error is set.

be The Backend where the error was set.
NULL if no error exists, otherwise the QofTime that the error was set.

Definition at line 251 of file qoferror.c.

00252 {
00253     QofError * qerr;
00254     GList * first;
00256     if (g_list_length(be->error_stack) == 0)
00257         return NULL;
00258     first = g_list_first (be->error_stack);
00259     qerr = (QofError*)first->data;
00260     return qerr->qt;
00261 }

QofErrorId qof_error_register ( const gchar *  err_message,
gboolean  use_file 

Generate and register a new error.

err_message The user-friendly string to add as an error, already marked for translation.
use_file TRUE if the session filename should be substituted in the string - err_message must contain a bare string format specifier: s. Note that flags, width, precision or size specifiers are not accepted and the filename is output in full, complete with the access_method. e.g. file:/home/user/app/data.xml
To use a different presentation of the filename or other customised strings, prepare the error message before registering it with QofError.

Registered errors are cleared when the session is destroyed.

Applications need to plan the use of locally registered error codes so that the same errors are not repeatedly registered.

The QofErrorId of this error.

Definition at line 91 of file qoferror.c.

00092 {
00093     QofError * qerr;
00095     ENTER (" ");
00096     qerr = g_new0 (QofError, 1);
00097     count++;
00099     count += ERR_LAST;
00100 #endif
00101     qerr->id = count;
00102     if (use_file)
00103     {
00104         gchar * spec;
00106         spec = g_strrstr (err_message, "%s");
00107         use_file = (spec) ? TRUE : FALSE;
00108     }
00109     qerr->use_file = use_file;
00110     qerr->message = g_strdup (err_message);
00111     g_hash_table_insert (error_table, GINT_TO_POINTER(qerr->id), qerr);
00112     LEAVE (" ");
00113     return qerr->id;
00114 }

void qof_error_set ( QofSession *  session,
QofErrorId  error 

Add an error to the stack for this session.

session The session that raised the error.
error The QofErrorId of the error to be recorded.

Definition at line 133 of file qoferror.c.

00134 {
00135     QofError * qerr, * set;
00137     g_return_if_fail (session);
00138     if (error == QOF_SUCCESS)
00139     {
00140         DEBUG (" passed success, not error.");
00141         return;
00142     }
00143     qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(error));
00144     if (!qerr)
00145     {
00146         DEBUG (" failed hash table lookup");
00147         return;
00148     }
00149     session->last_err = error;
00150     if (session->error_message)
00151         g_free (session->error_message);
00152     if (qerr->use_file)
00153         session->error_message = g_strdup_printf (qerr->message,
00154             qof_session_get_url (session));
00155     else
00156         session->error_message = g_strdup (qerr->message);
00157     if (!session->backend)
00158         return;
00159     /* create a new error for the list */
00160     set = g_new0 (QofError, 1);
00161     if (qerr->use_file)
00162         set->message = g_strdup_printf (qerr->message,
00163             qof_session_get_file_path (session));
00164     else
00165         set->message = g_strdup (qerr->message);
00166     set->id = error;
00167     set->qt = qof_time_get_current ();
00168     session->backend->error_stack = 
00169         g_list_prepend (session->backend->error_stack, set);
00171     session->backend->last_err = error;
00172 #endif
00173 }

void qof_error_unregister ( QofErrorId  id  ) 

Unregister an error.

Registered errors are normally freed when the session ends. Errors can also be unregistered (and freed) directly.

An unregistered error can not be set later.

Definition at line 117 of file qoferror.c.

00118 {
00119     QofError * qerr;
00120     gboolean result;
00122     ENTER (" ");
00123     qerr = g_hash_table_lookup (error_table, GINT_TO_POINTER(id));
00124     qof_error_free (qerr);
00125     result = g_hash_table_remove (error_table, 
00126         GINT_TO_POINTER(id));
00127     if (!result)
00128         LEAVE ("unable to remove registered error.");
00129     LEAVE (" ok.");
00130 }

Generated on Thu Jan 31 22:50:27 2008 for QOF by  doxygen 1.5.4