atobase  3.2.0
ATOMAS atobase
Error handling

Overview

If a method raises an error (at any severity level), the method and containing methods, will return immediately back to the application code.

API methods which can generate errors have the following characteristics:

All other methods:

Either of these types of methods can assert if invalid arguments are used or an out of memory condition occurs.

Where an error code is returned that is not ATO_ERR_OK, the ato_Ctx object has an ato_Err object. This can be used to retrieve details on the last error that occurred including any nested errors. There is a separate Error API to retrieve details of the error.

The errorcode associated with an error object, and returned by many of the API methods, is an int. Given the nature of C, it is not possible to guarantee non-overlapping codes, so each errorcode returned should be interpreted in relation to the method called. For convenience, each self-contained API contains a list of non-overlapping errorcodes as "#defines". The ato_Err object does contain the library and module that raised the error, which provides more information if required.

All errors have an associated severity level - see ato_eErrSeverity. While the catagorisation of some errors with a given severity level is somewhat arbitrary, the table below gives a rational for the catagorisation.

Currently all errors are given a severity level of "ATO_ESEVERITY_WARN" (the default).

Error severity

Error SeverityImplicationActionExample causes
ATO_ESEVERITY_FATAL Panic Halt (sometimes assertion) Coding errors; environment errors: out of memory, disc corruption, missing mandatory configuration data
ATO_ESEVERITY_ERR Affects all processing - cannot process any messages/transactions until fixed Warn user and go into RETRY until condition auto-corrects. If retry takes too long (or user cancels), escalate to FATAL Infrastructure errors: cannot contact server
ATO_ESEVERITY_WARN Current msg/transaction cannot be processed. Others may be fine Warn user and go into RETRY until condition auto-corrects. If retry takes too long (or user cancels), escalate to FATAL Business rule violated for a given message or transaction: missing or bad data; incorrect user input such as bad password

Iterating the error "stack"

It is recommended that dependent SDKs wrap errors returned by ATOBASE with their own SDK specific error codes. This implies that ATOBASE errors are always inner/nested errors. In addition ATOBASE errors may wrap other ATOBASE errors. For ease of use it is also recommended that dependant SKDs have non-overlapping errcodes.

ATOBASE errcodes are of the form ATO_ERR_... where there is an associated an associated error object attached to he current context (contexts must be thread specific).

In addition, any error object can contain a custom error object which is interpreted according to an additional error API that knows how to interpret the custom error object. Currently the only custom error object is related to reporting network SOAP errors. This is the case if the errcode, of the containing general error object, is set to ATO_ERR_NET_SOAP.

While the default logger will automatically log errors (the application can override the default logger), it may be appropriate to interpret the errors further. The generic way of doing this is to iterate "down" through the inner errors and for each error check appropriate details and interpret any custom error.

ato_Err *err = ato_ctx_err(ctx);
int errcode = ato_err_code(err);
for (; err; err = ato_err_inner(err)) {
errcode = ato_err_code(err);
printf("%s\n", ato_err_msg(err));
if (errcode == ATO_ERR_NET_SOAP) {
ato_ErrSoap *soaperr = ato_err_custom(err);
if (soaperr && ato_errsoap_issoaperr(soaperr)) {
ato_ErrSoapCode *code = NULL;
printf(" node=[%s]\n", ato_errsoap_node(soaperr));
printf(" reason=[%s]\n", ato_errsoap_reason(soaperr));
printf(" detail=[%s]\n", ato_errsoap_detail(soaperr));
for (code = ato_errsoap_code_firstv(soaperr); code; code = ato_errsoap_code_nextv(soaperr)) {
printf(" code value=[%s] ns=[%s]\n", ato_errsoap_code_value(code), ato_errsoap_code_ns(code));
}
} else {
printf(" SOAP error details not available\n");
}
}
}
ATO_EXPORT ato_Err * ato_ctx_err(ato_Ctx *ctx)
Get the error object associated with the current context, if any.
ATO_EXPORT const char * ato_err_msg(ato_Err *err)
Get the message attached to the error.
ATO_EXPORT void * ato_err_custom(ato_Err *err)
Get the custom object if any.
ATO_EXPORT ato_Err * ato_err_inner(ato_Err *err)
Get the nested/inner error object if any.
ATO_EXPORT int ato_err_code(ato_Err *err)
Get the error code.
struct _ato_Err ato_Err
The Error type.
Definition: err.h:17
ATO_EXPORT bool ato_errsoap_issoaperr(ato_ErrSoap *err)
Confirms whether or not the error object is of the expected type.
ATO_EXPORT ato_ErrSoapCode * ato_errsoap_code_nextv(ato_ErrSoap *err)
Get the next code of the collection.
struct _ato_ErrSoapCode ato_ErrSoapCode
This object represents a code or subcode node in a SOAP fault.
Definition: errsoap.h:21
ATO_EXPORT const char * ato_errsoap_node(ato_ErrSoap *err)
Decribes the service node where the error occured.
struct _ato_ErrSoap ato_ErrSoap
This object represents a SOAP fault.
Definition: errsoap.h:16
ATO_EXPORT const char * ato_errsoap_code_value(ato_ErrSoapCode *code)
Returns the value of the code/subcode.
ATO_EXPORT ato_ErrSoapCode * ato_errsoap_code_firstv(ato_ErrSoap *err)
Get the first code of the collection.
ATO_EXPORT const char * ato_errsoap_detail(ato_ErrSoap *err)
This contains low-level details of the fault and is only provided in non-production environments.
ATO_EXPORT const char * ato_errsoap_reason(ato_ErrSoap *err)
Describes the specifics of the particular error condition, and reflects the finest granularity of sub...
ATO_EXPORT const char * ato_errsoap_code_ns(ato_ErrSoapCode *code)
Returns the namespace of the code/subcode.
#define ATO_ERR_NET_SOAP
Network SOAP error returned by remote client.
Definition: types.h:217