Overview

The RoseError structure and several other typedefs are used during error reporting to describe messages, codes and severities.

This section also describes functions that customize error reporting. The RoseErrorReporter, RoseErrorContext, RoseErrorStats, and RoseErrorTrace classes also provide services and are described in separate sections.

RoseError (struct)

struct RoseError {
    RoseErrorCode	f_errcode;	// numeric code
    RoseStatus		f_severity;	// severity 
    const char *	f_detail;	// detail msg, printf format
    const char * 	f_summary;	// summary msg, fixed string
    const char * 	f_errsym;	// symbol for application use
};

The RoseError struct holds all information needed to describe an issue report, and the struct is passed to the reporting hook functions for output. The structure contains an error code, severity, printf-style detail message, and a fixed summary message. It also contains space for an application-specific error symbol.

When generating detail messages ( a message each time an issue is seen ), the reporting code will first try to use the printf-style f_detail field with any variable arguments passed to the reporting code. If this field is null, the reporting code will use the f_summary fixed string. If both are null, the reporting code will construct a message using the error code.

When generating summary messages using RoseErrorStats, the reporting code will only use the f_summary fixed string or construct a message using the error code, if needed.

An application may create a static array of these to describe all predefined errors issued by an application. A RoseErrorContext can search this array for calling predefined messages using the numeric error code. The numeric error codes may be duplicated between contexts, but it is not advisable to do so.

The following example shows some predefined messages.

RoseError bad_alias = {
    BAD_ALIASFILE,                 // #define for a numeric code
    ROSE_STATUS_WARNING,	   // This is a warning
    "Unable to open short name file: %s.",   // Detailed message
    "Bad short name file",   // summary
    "ROSE_EC_BAD_ALIASFILE"  // as a symbol
};


RoseError minimal_message = {
    ROSE_GENERAL,		// general code
    ROSE_STATUS_ERROR,		// error
    0,				// no detail message
    "Something bad happened",   // summary
    0				// no symbol
};

RoseErrorCode (typedef)

typedef unsigned long RoseErrorCode;

#define ROSE_NULL_ERROR_CODE	(RoseErrorCode) 0 
#define ROSE_GENERAL 		(RoseErrorCode) 1 	/* general error */
#define ROSE_MEMORY 		(RoseErrorCode) 2 	/* memory error */
#define ROSE_BAD_ERROR_CODE	(RoseErrorCode) 3 	/* code not found */
#define ROSE_USER_ERROR_CODE 	(RoseErrorCode) 0x8000

The RoseErrorCode typedef is an unsigned long integer value used by the error reporting code to identify messages numerically. Nothing in the ROSE library enforces uniqueness, but all codes defined by STEP Tools are unique. In addition to the codes described above, the file rose_errors.h defines codes used by file reading and general operations.

Codes above ROSE_USER_ERROR_CODE can be used by applications without fear of conflict. This value is also a bit flag for easy testing.

RoseStatus (typedef)

typedef unsigned RoseStatus;

#define ROSE_OK			((RoseStatus) 0)   /* things are fine */
#define ROSE_STATUS_MINOR	1   /* style things */
#define ROSE_STATUS_WARNING	2   /* may indicate deeper problems */
#define ROSE_STATUS_ERROR	3   /* broken, may be able to recover */
#define ROSE_STATUS_FATAL	4   /* broken, unable to recover  */

#define ROSE_STATUS_MASK	((RoseStatus) 0x7) /* bit mask for codes */
#define ROSE_STATUS_DISABLED	((RoseStatus) 0x8)  /* disable bit flag */
#define ROSE_STATUS_DEFAULT	((RoseStatus) 0x10)   /* default value */

The RoseStatus typedef is an unsigned integer value used by the error reporting code and as a return value for some functions. A zero value represents success (ROSE_OK) and a non-zero value indicates an issue of some seriousness from minor to fatal.

Within a RoseError severity, the bit flag ROSE_STATUS_DISABLED can be applied to turn off the message while retaining the original severity value. The rose_error_disable() and rose_error_enable() functions can also be used to do this.

When setting threshold values in a RoseErrorContext, the ROSE_STATUS_DEFAULT value is used to inherit the thresholds of the rose_ec() context. The ROSE_STATUS_MASK bit mask will force a status value to one of the base severities.

rose_ec() / rose_io_ec()

RoseErrorContext * rose_ec();            /* library context */
RoseErrorContext * rose_io_ec();         /* file io context */

The rose_ec() function returns the context used for general ROSE library messages. The rose_io_ec() function returns the context used for library I/O messages, like STEP Part 21 file errors. This context provides a separate reporting threshold to make sure that file error messages are still seen if the other library messages are turned off.

rose_error_dflt_fatal()

void rose_error_dflt_fatal(
    RoseErrorReporter * rpt, 
    const RoseError * err
    );
The rose_error_dflt_fatal() function is called by the RoseErrorReporter when the exit_threshold() has been met and the application has not set a fatal_fn() hook function. The function simply calls exit().

rose_error_dflt_report()

void rose_error_dflt_report(
    RoseErrorReporter * rpt, 
    const RoseError * err, 
    va_list ap
    );
The rose_error_dflt_report() function is called by the RoseErrorReporter when the report_threshold() has been met and the application has not set a report_fn() hook function. The function formats the message and prints it to the console.

rose_error_disable()

void rose_error_disable (RoseError *);

The rose_error_disable() and rose_error_enable() functions toggle the ROSE_STATUS_DISABLED bit flag on the severity of a RoseError structure. This is used to turn off the message while retaining the original severity value. The RoseErrorContext::disable() function is an easier way to work with predefined error codes.

rose_error_enable()

void rose_error_enable (RoseError *);

The rose_error_enable() functions clears the ROSE_STATUS_DISABLED bit flag on the severity of a RoseError structure. If the error was previously suppressed, it will be reported again. The RoseErrorContext::enable() function is an easier way to work with predefined error codes.

rose_error_format_fprintf()

void rose_error_format_fprintf(
    FILE * f, 
    RoseErrorReporter * rpt, 
    RoseErrorContext * ec,
    const RoseError * err, 
    va_list ap
    );
The rose_error_format_fprintf() function is provided to simplify custom error reporting code. It constructs a message with the normal ROSE library trace strings and formatting, then prints it to the given file descriptor. The function always appends a newline.

rose_error_format_sprintf()

void rose_error_format_sprintf(
    RoseStringObject &str, 
    RoseErrorReporter * rpt, 
    RoseErrorContext * ec,
    const RoseError * err, 
    va_list ap
    );
The rose_error_format_sprintf() function is provided to simplify custom error reporting code. It constructs a message with the normal ROSE library trace strings and formatting, then stores it in the string object where it can be used in a dialog box or other location.

The following is an example hook function for report_fn() that formats a message for display in a Windows dialog box.


void report_in_a_box(
    RoseErrorReporter * rpt, 
    RoseErrorContext * ec,
    const RoseError * err, 
    va_list ap
    )
{
    RoseStringObject msg;

    rose_error_format_sprintf (msg, rpt, ec, err, ap);

    CWnd * cw = AfxGetMainWnd();
    HWND mw = NULL;
    if (cw) mw = cw->m_hWnd; 

    MessageBox (mw, msg.as_const(), "WARNING", MB_ICONSTOP);
}