Mir 1.0
Mir application programming interface
Error handling system

Data Structures

struct  mirkl_error_t_
 Structure of error object. More...
 

Macros

#define MIRKL_NO_ERROR   NULL
 The best kind of (mirkl_error_t *)!
 
#define mirkl_error_create(err_code, child, msg)   (mirkl_error_create_i(MIRKL_ERRT_NORMAL,err_code,0,NULL,NULL,child,msg))
 Wrapper macro to collect file&line and func information.
 
#define mirkl_error_create_t(type, err_code, child, msg)   (mirkl_error_create_i(type,err_code,0,NULL,NULL,child,msg))
 Wrapper macro which allows to define the type of error.
 
#define mirkl_error_createf(err_code, child, fmt, ...)   (mirkl_error_createf_i(MIRKL_ERRT_NORMAL,err_code,0,NULL,NULL,child,fmt, __VA_ARGS__))
 Wrapper macro to collect file&line and func information.
 
#define mirkl_error_createf_t(type, err_code, child, fmt, ...)   (mirkl_error_createf_i(type,err_code,0,NULL,NULL,child,fmt, __VA_ARGS__))
 Wrapper macro which allows to define the type of error.
 
#define mirkl_error_aprwrap(status)   (mirkl_error_aprwrap_i(status,0,NULL,NULL))
 Wrapper macro to collect file&line and func information.
 
#define mirkl_error_aprwrapf(status, fmt, ...)   (mirkl_error_aprwrapf_i(status,0,NULL,NULL,fmt, __VA_ARGS__))
 Wrapper macro to collect file&line and func information.
 
#define mirkl_error_quick_wrap(child, new_msg)   (mirkl_error_quick_wrap_i(0,NULL,NULL,child,new_msg))
 Wrapper macro to collect file&line and func information.
 
#define MIRKL_WARNING(msg)   (mirkl_error_clear(mirkl_error_handle(mirkl_error_create_t(MIRKL_ERRT_WARNING,0,NULL,msg), mirkl_error_stdhandler, (void *)stdout)))
 

Typedefs

typedef struct mirkl_error_t_ mirkl_error_t
 Structure of error object.
 
typedef void(* mirkl_error_malfunction_handler_t) (mirkl_error_t *error)
 A type of function that handles an assertion failure or other internal malfunction detected. More...
 

Functions

void mirkl_error_set_type (mirkl_error_t *error, int type)
 Sets type of an error to type.
 
void mirkl_error_set_type_all (mirkl_error_t *error, int type)
 Sets type of an error and all of its childs to type.
 
mirkl_error_tmirkl_error_create_i (int err_type, int err_code, int line, const char *file, const char *func, mirkl_error_t *child, const char *message)
 Create a nested exception structure. More...
 
mirkl_error_tmirkl_error_createf_i (int err_type, int err_code, int line, const char *file, const char *func, mirkl_error_t *child, const char *fmt,...) __attribute__((format(printf
 
mirkl_error_tmirkl_error_aprwrap_i (apr_status_t status, int line, const char *file, const char *func)
 
mirkl_error_tmirkl_error_aprwrapf_i (apr_status_t status, int line, const char *file, const char *func, const char *fmt,...) __attribute__((format(printf
 
mirkl_error_tmirkl_error_quick_wrap_i (int line, const char *file, const char *func, mirkl_error_t *child, const char *new_msg)
 
mirkl_error_tmirkl_error_compose_create (mirkl_error_t *err1, mirkl_error_t *err2)
 
void mirkl_error_compose (mirkl_error_t *chain, mirkl_error_t *new_err)
 
mirkl_error_tmirkl_error_root_cause (mirkl_error_t *err)
 
mirkl_error_tmirkl_error_dup (mirkl_error_t *err)
 Create a new error that is a deep copy of err and return it.
 
void mirkl_error_clear (mirkl_error_t *error)
 Free the memory used by error, as well as all ancestors and descendants of error. More...
 
mirkl_error_tmirkl_error_handle (mirkl_error_t *err, void(*errhcb)(const char *, void *), void *args)
 
void mirkl_error_stdhandler (const char *msg, void *args)
 
void mirkl_error_walk (mirkl_error_t *err, void(*cb)(int, const char *, const char *, mirkl_uint32_t, const char *, void *), void *args)
 
mirkl_error_tmirkl_error_register (int *code, const char *msg)
 
mirkl_error_tmirkl_error_deregister (int code)
 
void mirkl_error_malfunction (mirkl_error_t *error)
 A helper function for the macros that report malfunctions. More...
 
mirkl_error_malfunction_handler_t mirkl_error_set_malfunction_handler (mirkl_error_malfunction_handler_t func)
 Cause subsequent malfunctions to be handled by func. More...
 
mirkl_error_malfunction_handler_t mirkl_error_get_malfunction_handler (void)
 Return the malfunction handler that is currently in effect.
 
void mirkl_error_serialize (mirkl_error_t *error, void **buffer, mirkl_size_t *length)
 Serialize an error to buffer. More...
 
void mirkl_error_deserialize (mirkl_error_t **error, void *buffer, mirkl_size_t length)
 DeSerialize an error to buffer. More...
 
mirkl_uint16_t mirkl_error_crc16 (mirkl_error_t *error)
 Calculate CRC16 of an error.
 
void mirkl_error_set_data (mirkl_error_t *err, void *data)
 Set user-defined data to the error.
 
void * mirkl_error_get_data (mirkl_error_t *err)
 Get previously defined data from the error.
 
void * mirkl_error_get_data_first (mirkl_error_t *err)
 Look-up the chain of errors and get first non-NULL data pointer.
 

Variables

mirkl_error_tMirklDLlistStopWalking
 

Types of errors

#define MIRKL_ERRT_NORMAL   0
 Error.
 
#define MIRKL_ERRT_WARNING   1
 Warning.
 
#define MIRKL_ERRT_MALFUNC   2
 Malfunction.
 
#define MIRKL_ERRT_ASSERT   3
 Assert.
 
#define MIRKL_ERRT_CUSTOM   4
 User-defined.
 

Statement macros for checking error values

#define MIRKL_ERR(expr)
 Most basic macro for checking for errors. More...
 
#define MIRKL_ERR_ABORT(expr)
 Calls standard error handler and aborts program if expr returns an error. More...
 
#define MIRKL_ERR_NC(expr, code)
 Returns error only if it is not equal to code. More...
 
#define MIRKL_ERR_NCDO(expr, code, doexpr)
 Returns error only if it is not equal to code, otherwise frees the error and executes doexpr expression. More...
 
#define MIRKL_ERR_EXE(expr, exexpr)
 Before returning error executes expression. More...
 
#define MIRKL_ERR_NCDO_EXE(expr, code, doexpr, exexpr)
 Returns error (after executing exexpr expression) only if it is not equal to code, otherwise frees the error and executes doexpr expression. More...
 
#define MIRKL_ERR_W(expr, wrap_msg)
 This macro will wrap the error with the specified text before returning the error. More...
 
#define MIRKL_ERR_NC_W(expr, code, wrap_msg)
 Wraps text message and returns error only if it is not equal to code. More...
 
#define MIRKL_ERR_EXE_W(expr, exexpr, wrap_msg)
 Does same as MIRKL_ERR_W but also executes expression exexpr. More...
 
#define MIRKL_ERR_NC_EXE_W(expr, code, exexpr, wrap_msg)
 Does same as MIRKL_ERR_NC_W but also executes expression exexpr. More...
 
#define MIRKL_ERR_INT(expr, retint)
 A statement macro, similar to MIRKL_ERR, but returns integer instead of pointer to mirkl_error_t. More...
 
#define MIRKL_ERR_E(expr, err)
 If execution of expr returned and error, appends err and returns common error. More...
 
#define MIRKL_ERR_E_W(expr, err, msg)
 Works as MIRKL_ERR_E and wraps additionally msg string. More...
 
#define MIRKL_ERR_E_GOTO(expr, err, labl)
 If execution of expr returned an error, appends err and jumps to labl label. More...
 
#define MIRKL_ERR_E_W_GOTO(expr, err, msg, labl)
 Works as MIRKL_ERR_E_GOTO and wraps additionally msg string. More...
 

Abnormal process termination

#define MIRKL_ASSERT(expr)   ((void)(0))
 Check that a condition is true: if not, report an error and terminate the program. More...
 
#define MIRKL_ASSERT_W(expr, msg)   ((void)(0))
 Similar to MIRKL_ASSERT but also allows to add user message msg.
 
#define MIRKL_ASSERT_E(expr, err)   ((void)(0))
 Similar to MIRKL_ASSERT but also allows to add an error err.
 
#define MIRKL_MALFUNCTION()
 Report that an internal malfunction has occurred, and terminate the program. More...
 
#define MIRKL_ABORT()
 Same as MIRKL_MALFUNCTION. More...
 
#define MIRKL_ABORT_E(err)
 Similar to MIRKL_ABORT but also takes info from error err. More...
 
#define MIRKL_ABORT_W(msg)
 Similar to MIRKL_ABORT but also takes info from string msg. More...
 
#define MIRKL_ABORT_E_W(err, msg)
 Similar to MIRKL_ABORT but also takes err as a child error and info from string msg. More...
 

Detailed Description

Part of the code and ideas have been taken from Subversion project.

Macro Definition Documentation

◆ MIRKL_ABORT

#define MIRKL_ABORT ( )
Value:
do { \
mirkl_error_malfunction(mirkl_error_create_t(MIRKL_ERRT_MALFUNC,0,NULL,"Impossible to continue. Aborting...")); \
} while (0)
#define MIRKL_ERRT_MALFUNC
Malfunction.
Definition: mirkl_error.h:68
#define mirkl_error_create_t(type, err_code, child, msg)
Wrapper macro which allows to define the type of error.
Definition: mirkl_error.h:126

Same as MIRKL_MALFUNCTION.

◆ MIRKL_ABORT_E

#define MIRKL_ABORT_E (   err)
Value:
do { \
mirkl_error_malfunction(mirkl_error_create_t(MIRKL_ERRT_MALFUNC,0,(err),"Impossible to continue. Aborting...")); \
} while (0)

Similar to MIRKL_ABORT but also takes info from error err.

◆ MIRKL_ABORT_E_W

#define MIRKL_ABORT_E_W (   err,
  msg 
)
Value:
do { \
mirkl_error_malfunction(mirkl_error_create_t(MIRKL_ERRT_MALFUNC,0,(err),(msg))); \
} while (0)

Similar to MIRKL_ABORT but also takes err as a child error and info from string msg.

◆ MIRKL_ABORT_W

#define MIRKL_ABORT_W (   msg)
Value:
do { \
mirkl_error_malfunction(mirkl_error_create_t(MIRKL_ERRT_MALFUNC,0,NULL,(msg))); \
} while (0)

Similar to MIRKL_ABORT but also takes info from string msg.

◆ MIRKL_ASSERT

#define MIRKL_ASSERT (   expr)    ((void)(0))

Check that a condition is true: if not, report an error and terminate the program.

If the Boolean expression expr is true, do nothing. Otherwise, act as determined by the current "malfunction handler" which may have been specified by a call to mirkl_error_set_malfunction_handler() or else is the default handler as specified in that function's documentation.

Note
The intended use of this macro is to check a condition that cannot possibly be false unless there is a bug in the program.
The condition IS compiled out in release-mode builds.

◆ MIRKL_ERR

#define MIRKL_ERR (   expr)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if (mirkl_err__temp) \
return mirkl_err__temp; \
} while (0)

Most basic macro for checking for errors.

Evaluate expr. If it yields an error, return that error from the current function. Otherwise, continue.

The do { ... } while (0) wrapper has no semantic effect, but it makes this macro syntactically equivalent to the expression statement it resembles. Without it, statements like

if (a)
MIRKL_ERR (some operation);
else
foo;
#define MIRKL_ERR(expr)
Most basic macro for checking for errors.
Definition: mirkl_error.h:293

would not mean what they appear to.

◆ MIRKL_ERR_ABORT

#define MIRKL_ERR_ABORT (   expr)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp) { \
mirkl_error_clear(mirkl_error_handle(mirkl_err__temp, mirkl_error_stdhandler, (void *)stderr)); \
abort();} \
} while (0)

Calls standard error handler and aborts program if expr returns an error.

◆ MIRKL_ERR_E

#define MIRKL_ERR_E (   expr,
  err 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
err = mirkl_error_compose_create(mirkl_err__temp, err); \
return err;} \
} while (0)
mirkl_error_t * mirkl_error_compose_create(mirkl_error_t *err1, mirkl_error_t *err2)

If execution of expr returned and error, appends err and returns common error.

◆ MIRKL_ERR_E_GOTO

#define MIRKL_ERR_E_GOTO (   expr,
  err,
  labl 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
err = mirkl_error_compose_create(mirkl_err__temp, err); \
goto labl;} \
} while (0)

If execution of expr returned an error, appends err and jumps to labl label.

◆ MIRKL_ERR_E_W

#define MIRKL_ERR_E_W (   expr,
  err,
  msg 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
err = mirkl_error_compose_create(mirkl_err__temp, err); \
return mirkl_error_quick_wrap(err, msg);} \
} while (0)
#define mirkl_error_quick_wrap(child, new_msg)
Wrapper macro to collect file&line and func information.
Definition: mirkl_error.h:222

Works as MIRKL_ERR_E and wraps additionally msg string.

◆ MIRKL_ERR_E_W_GOTO

#define MIRKL_ERR_E_W_GOTO (   expr,
  err,
  msg,
  labl 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
err = mirkl_error_quick_wrap(mirkl_error_compose_create(mirkl_err__temp, err), msg); \
goto labl;} \
} while (0)

Works as MIRKL_ERR_E_GOTO and wraps additionally msg string.

◆ MIRKL_ERR_EXE

#define MIRKL_ERR_EXE (   expr,
  exexpr 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
exexpr; \
return mirkl_err__temp;} \
} while (0)

Before returning error executes expression.

◆ MIRKL_ERR_EXE_W

#define MIRKL_ERR_EXE_W (   expr,
  exexpr,
  wrap_msg 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
exexpr; \
return mirkl_error_quick_wrap(mirkl_err__temp, wrap_msg);} \
} while (0)

Does same as MIRKL_ERR_W but also executes expression exexpr.

◆ MIRKL_ERR_INT

#define MIRKL_ERR_INT (   expr,
  retint 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
mirkl_error_clear(mirkl_err__temp); \
return (retint);} \
} while (0)

A statement macro, similar to MIRKL_ERR, but returns integer instead of pointer to mirkl_error_t.

◆ MIRKL_ERR_NC

#define MIRKL_ERR_NC (   expr,
  code 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
if(mirkl_err__temp->err_code == (code)) \
mirkl_error_clear(mirkl_err__temp); \
else \
return mirkl_err__temp; \
} \
} while (0)

Returns error only if it is not equal to code.

◆ MIRKL_ERR_NC_EXE_W

#define MIRKL_ERR_NC_EXE_W (   expr,
  code,
  exexpr,
  wrap_msg 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
if(mirkl_err__temp->err_code == (code)) \
mirkl_error_clear(mirkl_err__temp); \
else{ \
exexpr; \
return mirkl_error_quick_wrap(mirkl_err__temp, wrap_msg);} \
} \
} while (0)

Does same as MIRKL_ERR_NC_W but also executes expression exexpr.

◆ MIRKL_ERR_NC_W

#define MIRKL_ERR_NC_W (   expr,
  code,
  wrap_msg 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
if(mirkl_err__temp->err_code == (code)) \
mirkl_error_clear(mirkl_err__temp); \
else \
return mirkl_error_quick_wrap(mirkl_err__temp, wrap_msg); \
} \
} while (0)

Wraps text message and returns error only if it is not equal to code.

◆ MIRKL_ERR_NCDO

#define MIRKL_ERR_NCDO (   expr,
  code,
  doexpr 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
if(mirkl_err__temp->err_code == (code)){ \
mirkl_error_clear(mirkl_err__temp); \
doexpr;} \
else \
return mirkl_err__temp; \
} \
} while (0)

Returns error only if it is not equal to code, otherwise frees the error and executes doexpr expression.

◆ MIRKL_ERR_NCDO_EXE

#define MIRKL_ERR_NCDO_EXE (   expr,
  code,
  doexpr,
  exexpr 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if(mirkl_err__temp){ \
if(mirkl_err__temp->err_code == (code)){ \
mirkl_error_clear(mirkl_err__temp); \
doexpr;} \
else{ \
exexpr; \
return mirkl_err__temp;} \
} \
} while (0)

Returns error (after executing exexpr expression) only if it is not equal to code, otherwise frees the error and executes doexpr expression.

◆ MIRKL_ERR_W

#define MIRKL_ERR_W (   expr,
  wrap_msg 
)
Value:
do { \
mirkl_error_t *mirkl_err__temp = (expr); \
if (mirkl_err__temp) \
return mirkl_error_quick_wrap(mirkl_err__temp, wrap_msg); \
} while (0)

This macro will wrap the error with the specified text before returning the error.

◆ MIRKL_MALFUNCTION

#define MIRKL_MALFUNCTION ( )
Value:
do { \
mirkl_error_malfunction(mirkl_error_create_t(MIRKL_ERRT_MALFUNC,0,NULL,"Internal malfunction")); \
} while (0)

Report that an internal malfunction has occurred, and terminate the program.

Act as determined by the current "malfunction handler" which may have been specified by a call to mirkl_error_set_malfunction_handler() or else is the default handler as specified in that function's documentation.

Note
The intended use of this macro is where execution reaches a point that cannot possibly be reached unless there is a bug in the program.

◆ MIRKL_WARNING

#define MIRKL_WARNING (   msg)    (mirkl_error_clear(mirkl_error_handle(mirkl_error_create_t(MIRKL_ERRT_WARNING,0,NULL,msg), mirkl_error_stdhandler, (void *)stdout)))

Macro to print warning messages.

Typedef Documentation

◆ mirkl_error_malfunction_handler_t

typedef void(* mirkl_error_malfunction_handler_t) (mirkl_error_t *error)

A type of function that handles an assertion failure or other internal malfunction detected.

The function may alter thi behaviour according to compile-time and run-time and even interactive conditions.

Function Documentation

◆ mirkl_error_aprwrap_i()

mirkl_error_t * mirkl_error_aprwrap_i ( apr_status_t  status,
int  line,
const char *  file,
const char *  func 
)

Create error wrapping status code from an APR function.

◆ mirkl_error_aprwrapf_i()

mirkl_error_t * mirkl_error_aprwrapf_i ( apr_status_t  status,
int  line,
const char *  file,
const char *  func,
const char *  fmt,
  ... 
)

Wrap a status from an APR function. If fmt is NULL, this is equivalent to mirkl_error_create(status,NULL,NULL). Otherwise, the error message is constructed by formatting fmt and the following arguments, and then appending ": " and the error message corresponding to status.

◆ mirkl_error_clear()

void mirkl_error_clear ( mirkl_error_t error)

Free the memory used by error, as well as all ancestors and descendants of error.

Unlike other Subversion objects, errors are managed explicitly; you MUST clear an error if you are ignoring it, or you are leaking memory. For convenience, error may be NULL, in which case this function does nothing; thus, #mirkl_error_clear(mirkl_foo(...)) works as an idiom to ignore errors.

◆ mirkl_error_compose()

void mirkl_error_compose ( mirkl_error_t chain,
mirkl_error_t new_err 
)

Add new_err to the end of chain's chain of errors. The new_err chain will be copied into chain's pool and destroyed, so new_err itself becomes invalid after this function.

◆ mirkl_error_compose_create()

mirkl_error_t * mirkl_error_compose_create ( mirkl_error_t err1,
mirkl_error_t err2 
)

Compose two errors, returning err1. Either or both of err1 and err2 may be MIRKL_NO_ERROR. If one of the errors is MIRKL_NO_ERROR, the other is returned. If both are MIRKL_NO_ERROR, MIRKL_NO_ERROR is returned. If both are not MIRKL_NO_ERROR, mirkl_error_compose is called, i.e. err2 will follow err1 in the chain of the returned error and err2 is invalid after this function.

◆ mirkl_error_create_i()

mirkl_error_t * mirkl_error_create_i ( int  err_type,
int  err_code,
int  line,
const char *  file,
const char *  func,
mirkl_error_t child,
const char *  message 
)

Create a nested exception structure.

Input: an APR or MirKL custom error code, a "child" error to wrap, a specific message

Returns
A new error structure (containing the old one).
Note
Errors are always allocated in a subpool of the global pool, since an error's lifetime is generally not related to the lifetime of any convenient pool. Errors must be freed with mirkl_error_clear(). The specific message should be NULL if there is nothing to add to the general message associated with the error code.

If creating the "bottommost" error in a chain, pass NULL for the child argument.

◆ mirkl_error_createf_i()

mirkl_error_t * mirkl_error_createf_i ( int  err_type,
int  err_code,
int  line,
const char *  file,
const char *  func,
mirkl_error_t child,
const char *  fmt,
  ... 
)

Create an error structure with the given err_type, err_code and child, with a printf-style error message produced by passing fmt and arguments.

◆ mirkl_error_deserialize()

void mirkl_error_deserialize ( mirkl_error_t **  error,
void *  buffer,
mirkl_size_t  length 
)

DeSerialize an error to buffer.

Parameters
[in]bufferbinary data, serialized error.
[in]lengthlength of the buffer.
[out]errorcreated from the serialized data.

◆ mirkl_error_malfunction()

void mirkl_error_malfunction ( mirkl_error_t error)

A helper function for the macros that report malfunctions.

Handle a malfunction by calling the current "malfunction handler" which may have been specified by a call to mirkl_error_set_malfunction_handler() or else is the default handler as specified in that function's documentation.

Note
Passes error to the handler.

◆ mirkl_error_quick_wrap_i()

mirkl_error_t * mirkl_error_quick_wrap_i ( int  line,
const char *  file,
const char *  func,
mirkl_error_t child,
const char *  new_msg 
)

A quick n' easy way to create a wrapped exception with your own message, before throwing it up the stack. (It uses all of the child's fields.)

◆ mirkl_error_root_cause()

mirkl_error_t * mirkl_error_root_cause ( mirkl_error_t err)

Return the root cause of err by finding the last error in its chain (e.g. it or its children). err may be MIRKL_NO_ERROR, in which case MIRKL_NO_ERROR is returned.

◆ mirkl_error_serialize()

void mirkl_error_serialize ( mirkl_error_t error,
void **  buffer,
mirkl_size_t *  length 
)

Serialize an error to buffer.

The length of the filled-in buffer is in length on output.

Note
The parameter buffer is automatially allocated, you are responsible for freeing it after usage of this function.

◆ mirkl_error_set_malfunction_handler()

mirkl_error_malfunction_handler_t mirkl_error_set_malfunction_handler ( mirkl_error_malfunction_handler_t  func)

Cause subsequent malfunctions to be handled by func.

Return the handler that was previously in effect. func may not be NULL.

Variable Documentation

◆ MirklDLlistStopWalking

mirkl_error_t* MirklDLlistStopWalking
extern

Special preallocated error, which causes functions mirkl_dl_mwalk_err_first() to stop walking through the lists if a callback function returns this error. The walking functions do not return this error.