9 #ifndef __AFW_ERROR_H__
10 #define __AFW_ERROR_H__
33 #define AFW_ERROR_RV_SOURCE_ID_Z_NULL NULL
40 #define AFW_ERROR_RV_SOURCE_ID_Z_apr "apr"
47 #define AFW_ERROR_RV_SOURCE_ID_Z_icu "icu"
138 #define AFW_ERROR_CLEAR_PARTIAL(__ERROR_) \
140 (char *)&((__ERROR_)->code), \
143 (char *)&((__ERROR_)->decode_rv_wa[0]) - \
144 (char *)&((__ERROR_)->code) \
171 #define AFW_ERROR_FOOTPRINT(_footprint_) \
172 footprint.z = _footprint_; \
173 footprint.source_z = AFW__FILE_LINE__;
182 #define AFW_THROW_UNHANDLED_ERROR(unhandled_error, _ERROR, _CODE, _RV_SOURCE_ID, _RV, _MESSAGE_Z) \
184 (_ERROR)->code = afw_error_code_ ## _CODE; \
185 (_ERROR)->source_z = AFW__FILE_LINE__;\
186 (_ERROR)->rv_source_id_z = #_RV_SOURCE_ID; \
187 (_ERROR)->rv = _RV; \
188 (_ERROR)->rv_decoded_z = NULL; \
189 (_ERROR)->message_z = _MESSAGE_Z; \
190 longjmp((unhandled_error)->throw_jmp_buf, afw_error_code_ ##_CODE); \
200 #define AFW_SUCCESS(__ERROR_) ((__ERROR_)->code == afw_error_code_none)
208 #define AFW_ERROR_OCCURRED(__ERROR_) ((__ERROR_)->code != afw_error_code_none)
212 jmp_buf throw_jmp_buf;
271 #define AFW_THROW(xctx) \
272 longjmp(((xctx)->current_try->throw_jmp_buf), (xctx)->error->code)
283 #define AFW_THROW_ERROR_Z(code, message_z, xctx) \
285 afw_error_set_z(afw_error_code_ ## code, \
286 AFW__FILE_LINE__, message_z, xctx); \
287 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
301 #define AFW_THROW_ERROR_RV_Z(code, rv_source_id, rv, message_z, xctx) \
303 afw_error_rv_set_z(afw_error_code_ ## code, \
304 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
305 AFW__FILE_LINE__, message_z, xctx); \
306 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
319 #define AFW_THROW_ERROR_FZ(code, xctx, format_z, ...) \
321 afw_error_set_fz(afw_error_code_ ## code, \
322 AFW__FILE_LINE__, xctx, format_z, __VA_ARGS__); \
323 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
338 #define AFW_THROW_ERROR_RV_FZ(code, rv_source_id, rv, xctx, format_z, ...) \
340 afw_error_rv_set_fz(afw_error_code_ ## code, \
341 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
342 AFW__FILE_LINE__, xctx, format_z, __VA_ARGS__); \
343 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
355 #define AFW_THROW_ERROR_VZ(code, format_z, ap, xctx) \
357 afw_error_set_vz(afw_error_code_ ## code, \
358 AFW__FILE_LINE__, format_z, ap, xctx); \
359 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
371 #define AFW_THROW_ERROR_RV_VZ(code, rv_source_id, rv, format_z, ap, xctx) \
373 afw_error_rv_set_vz(afw_error_code_ ## code, \
374 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
375 AFW__FILE_LINE__, format_z, ap, xctx); \
376 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
388 #define AFW_THROW_ERROR_FOOTPRINT_Z(code, message_z, xctx) \
390 afw_error_set_z(afw_error_code_ ## code, \
391 footprint.source_z, message_z, xctx); \
392 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
408 #define AFW_THROW_ERROR_FOOTPRINT_RV_Z(code, rv_source_id, rv, message_z, xctx) \
410 afw_error_rv_set_z(afw_error_code_ ## code, \
411 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
412 footprint.source_z, message_z, xctx); \
413 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
428 #define AFW_THROW_ERROR_FOOTPRINT_FZ(code, xctx, format_z, ...) \
430 afw_error_set_fz(afw_error_code_ ## code, \
431 footprint.source_z, xctx, format_z, __VA_ARGS__); \
432 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
449 #define AFW_THROW_ERROR_FOOTPRINT_RV_FZ(code, rv_source_id, rv, xctx, format_z, ...) \
451 afw_error_rv_set_fz(afw_error_code_ ## code, \
452 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
453 footprint.source_z, xctx, format_z, __VA_ARGS__); \
454 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
468 #define AFW_THROW_ERROR_FOOTPRINT_VZ(code, format_z, ap, xctx) \
470 afw_error_set_vz(afw_error_code_ ## code, \
471 footprint.source_z, format_z, ap, xctx); \
472 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
486 #define AFW_THROW_ERROR_FOOTPRINT_RV_VZ(code, rv_source_id, rv, format_z, ap, xctx) \
488 afw_error_rv_set_vz(afw_error_code_ ## code, \
489 AFW_ERROR_RV_SOURCE_ID_Z_ ## rv_source_id, rv, \
490 footprint.source_z, format_z, ap, xctx); \
491 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_ ## code)); \
499 #define AFW_THROW_MEMORY_ERROR(xctx) \
501 afw_error_set_z(afw_error_code_memory, \
502 AFW__FILE_LINE__, "Memory error", xctx); \
503 longjmp(((xctx)->current_try->throw_jmp_buf), (afw_error_code_memory)); \
525 #define AFW_ERROR_INTERNAL_ON_UNHANDLED(__TRY_) \
526 (__TRY_).prev = NULL;\
527 if ((setjmp((__TRY_).throw_jmp_buf)) != 0)
539 #define AFW_ERROR_COPY(to, from) \
540 memcpy((to), (from), sizeof(afw_error_t)); \
541 if ((from)->message_z == &(from)->message_wa[0]) { \
542 (to)->message_z = &(to)->message_wa[0]; \
544 if ((from)->rv_decoded_z == &(from)->decode_rv_wa[0]) { \
545 (to)->rv_decoded_z = &(to)->decode_rv_wa[0]; \
554 #define AFW_ERROR_THROWN ((const afw_error_t *)&this_THROWN_ERROR)
637 afw_size_t this_TOP_OFFSET; \
638 afw_try_t this_TRY; \
639 afw_error_t this_THROWN_ERROR; \
640 afw_boolean_t this_ERROR_OCCURRED = false; \
641 afw_boolean_t this_ERROR_CAUGHT = false; \
642 AFW_POSSIBLY_UNUSED_VARIABLE afw_boolean_t this_FINALLY_ENTERED = false; \
643 this_TRY.prev = xctx->current_try;\
644 xctx->current_try = &this_TRY;\
645 this_TOP_OFFSET = xctx->evaluation_stack->top - \
646 xctx->evaluation_stack->first; \
648 if (setjmp(this_TRY.throw_jmp_buf) != 0) { \
649 AFW_ERROR_COPY(&this_THROWN_ERROR, xctx->error); \
650 AFW_ERROR_CLEAR_PARTIAL(xctx->error); \
651 if (this_ERROR_OCCURRED) { \
652 this_THROWN_ERROR.recursive_error = true; \
653 this_ERROR_CAUGHT = false; \
656 this_ERROR_OCCURRED = true; \
668 #define AFW_CATCH( __CODE_ ) \
672 if (xctx->error->code == (afw_error_code_ ## __CODE_)) \
674 this_ERROR_CAUGHT = true; \
684 #define AFW_CATCH_UNHANDLED \
689 this_ERROR_CAUGHT = true; \
702 #define AFW_FINALLY \
707 if (this_FINALLY_ENTERED) { \
708 this_THROWN_ERROR.recursive_error_in_finally = true; \
711 this_FINALLY_ENTERED = true; \
731 xctx->current_try = this_TRY.prev; \
732 if (this_ERROR_OCCURRED && !this_ERROR_CAUGHT) { \
733 AFW_ERROR_COPY(xctx->error, &this_THROWN_ERROR); \
734 longjmp(xctx->current_try->throw_jmp_buf, this_THROWN_ERROR.code); \
736 xctx->evaluation_stack->top = xctx->evaluation_stack->first + \
750 #define AFW_MARK_UNHANDLED \
751 this_ERROR_CAUGHT = false; \
879 #define afw_error_source_file(error) \
880 afw_utf8_z_source_file((error)->source_z)
AFW_DEFINE(const afw_object_t *)
#define AFW_DECLARE_ELLIPSIS(type)
Declare a public afw function with variable arguments.
#define AFW_BEGIN_DECLARES
#define AFW_DECLARE(type)
Declare a public afw function.
Interfaceafw_interface header.
enum afw_error_code_e afw_error_code_t
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
apr_size_t afw_size_t
size_t.
enum afw_log_priority_e afw_log_priority_t
Log levels. See afw_log.h for more information.
afw_error_http_status(const afw_error_t *error)
Returns http status for error.
int afw_error_print_with_xctx(FILE *fp, const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Print error when xctx is available.
int afw_error_print(FILE *fp, const afw_error_t *error)
Print error.
void afw_error_write_log(afw_log_priority_t priority, const afw_error_t *error, afw_xctx_t *xctx)
Write error to environment log.
const afw_utf8_z_t * afw_error_code_id_z(const afw_error_t *error)
Returns error->code id.
void afw_error_add_to_object(const afw_object_t *object, const afw_error_t *error, afw_xctx_t *xctx)
Add error info to existing object using specified pool.
const afw_utf8_z_t * afw_error_message(afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Build message in xctx error message_wa and return pointer.
const afw_utf8_t * afw_error_to_utf8(const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Convert error to utf8.
struct afw_error_footprint_s afw_error_footprint_t
error footprint
afw_boolean_t afw_error_allow_in_response(afw_error_code_t code)
Determine if the error object for code is allowed in HTTP response.
const afw_object_t * afw_error_to_object(const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Create an object with error info in specified pool.
const afw_utf8_z_t * afw_error_message_vz(const afw_utf8_z_t *format, va_list ap, afw_xctx_t *xctx)
Build message in xctx error message_wa and return pointer.
Contextual information provided in some values.
Adaptive Framework Error Context.
Adaptive Framework Error.
afw_error_code_t code
Error code.
afw_boolean_t recursive_error
Recursive error.
afw_boolean_t recursive_error_in_finally
Recursive error in finally.
const afw_utf8_z_t * rv_source_id_z
This is the source of the non-zero rv.
const afw_utf8_z_t * message_z
Message.
afw_utf8_z_t message_wa_safety_zero_terminator
Makes sure there is a zero terminator after message_wa.
const afw_compile_value_contextual_t * contextual
Contextual information or NULL.
const afw_utf8_t * backtrace
If not memory error and afw_os_backtrace() supplies one.
int rv
If non-zero, this is rc, rv, or any int value related to error.
const afw_utf8_t * parser_source
If syntax error, this is partial/full source or NULL.
afw_utf8_z_t decode_rv_wa[23]
Place to optionally hold rv_decoded_z.
const afw_utf8_z_t * source_z
File:line in source error was thrown.
const afw_utf8_z_t * rv_decoded_z
Human readable decode of rv.
afw_utf8_z_t message_wa[255]
Place to optionally hold message_z.
afw_utf8_z_t decode_rv_wa_safety_zero_terminator
Makes sure there is a zero terminator after decode_rv_wa.
afw_size_t parser_cursor
If syntax error, this is cursor when parse error occurred or 0.
Interface afw_object public struct.
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Interface afw_xctx public struct.