20 int http_response_code;
35 #define XX(id, error_allow_in_response, http_response_code, description) \
37 AFW_UTF8_LITERAL( #id ), \
38 error_allow_in_response, \
40 AFW_UTF8_LITERAL( #description ), \
41 AFW_UTF8_LITERAL( #http_response_code " " #description ) \
49 static const afw_utf8_t impl_s_a_html_unknown =
66 xctx->error->
code = code;
73 if (code != afw_error_code_memory) {
78 if (rv != 0 && rv_source_id_z)
80 rv_source_id.s = rv_source_id_z;
81 rv_source_id.len = strlen(rv_source_id_z);
99 afw_error_rv_set_z(code, NULL, 0, source_z, message_z,
115 va_start(ap, format_z);
116 vsnprintf((
char *)&(xctx->error->
message_wa[0]),
118 (
const char *)format_z, ap);
119 afw_error_rv_set_z(code, rv_source_id_z, rv, source_z,
133 va_start(ap, format_z);
134 vsnprintf((
char *)&(xctx->error->
message_wa[0]),
136 (
const char *)format_z, ap);
137 afw_error_rv_set_z(code, NULL, 0, source_z,
152 vsnprintf((
char *)&(xctx->error->
message_wa[0]),
154 (
const char *)format_z, ap);
155 afw_error_rv_set_z(code, rv_source_id_z, rv, source_z,
167 vsnprintf((
char *)&(xctx->error->
message_wa[0]),
169 (
const char *)format_z, ap);
170 afw_error_rv_set_z(code, NULL, 0, source_z,
176 impl_write_source_lines(
188 int offset_cell_octets;
189 int line_cell_octets;
193 &number_of_lines, &max_column_number, source, 4, xctx);
206 for (j = 0, offset = 0; j < source->len; j++)
208 if (source->s[j] ==
'\t')
219 offset_cell_octets, offset,
220 line_cell_octets, line);
222 if (error_line == line) {
229 if (source->s[j] ==
'\n')
240 if (line == 0 || !new_line) {
248 impl_evaluation_backtrace(
270 int offset_cell_octets;
271 int line_cell_octets;
272 int column_cell_octets;
280 caret_on_error =
false;
281 last_contextual = NULL;
282 offset_cell_octets = 0;
283 line_cell_octets = 0;
284 column_cell_octets = 0;
291 &error_line, &error_column,
297 impl_write_source_lines(w, error->
parser_source, error_line, p, xctx);
301 for (entry_number = 0,
302 i = xctx->evaluation_stack->top - xctx->evaluation_stack->first,
303 parameter_number = 0;
308 if (!xctx->evaluation_stack->first[i].value) {
314 if (xctx->evaluation_stack->first[i].entry_id ==
315 &afw_s_parameter_number)
319 xctx->evaluation_stack->first[i].parameter_number;
325 if (xctx->evaluation_stack->first[i].parameter_number < 100)
328 "--- Unexpected parameter number. "
329 "Evaluation stack error.",
333 xctx->evaluation_stack->first[i].parameter_number;
345 if (!last_contextual ||
346 last_contextual->source_location !=
350 if (entry_number == 0) {
352 &error_line, &error_column,
357 caret_on_error =
false;
380 else if (!last_contextual ||
381 (last_contextual->compiled_value &&
382 last_contextual->compiled_value->full_source !=
387 &number_of_lines, &max_column_number,
414 &line_number, &column_number,
421 info.contextual->
value_offset, line_number, column_number);
427 &line_number, &column_number,
433 offset, line_number, column_number);
442 for (j = 0, offset = 0;
455 snprintf(buf2,
sizeof(buf2),
458 offset_cell_octets, offset,
459 line_cell_octets, line);
461 if (caret_on_error && error_line == line) {
482 if (line == 0 || !new_line) {
495 &line_number, &column_number,
502 line_cell_octets, line_number,
503 column_cell_octets, column_number);
525 if (parameter_number != 0) {
531 parameter_number = 0;
535 last_contextual = info.contextual;
560 xctx->env->flag_index_response_error_contextual, xctx);
562 xctx->env->flag_index_response_error_backtraceEvaluation, xctx);
564 xctx->env->flag_index_response_error_backtrace, xctx);
567 evaluation_backtrace = impl_evaluation_backtrace(error, p, xctx);
593 (error->rv_source_id_z) ? (
char *)error->rv_source_id_z :
"",
594 (error->rv_source_id_z) ?
":" :
"",
596 (error->rv_decoded_z) ?
"-" :
"",
597 (error->rv_decoded_z) ? (
char *)error->rv_decoded_z :
"",
600 (!error->recursive_error)
602 : ((error->recursive_error_in_finally)
603 ?
" recursive error in finally"
604 :
" recursive error in catch"),
607 (do_contextual && error->contextual && error->contextual->source_location)
608 ?
" source_location=" :
"",
609 (do_contextual && error->contextual && error->contextual->source_location)
610 ? error->contextual->source_location->len : 0,
611 (do_contextual && error->contextual && error->contextual->source_location)
612 ? (
char *)error->contextual->source_location->s :
"",
613 (do_contextual && error->contextual && error->contextual->value_offset != 0)
615 (do_contextual && error->contextual && error->contextual->value_offset != 0)
616 ? error->contextual->value_offset
620 (do_evaluation_backtrace && evaluation_backtrace)
621 ?
"\n\nEvaluation backtrace:\n" :
"",
622 (do_evaluation_backtrace && evaluation_backtrace)
623 ? evaluation_backtrace->len : 0,
624 (do_evaluation_backtrace && evaluation_backtrace)
625 ? (
char *)evaluation_backtrace->s :
"",
628 (do_code_backtrace && error->backtrace) ?
"\nCode backtrace:\n" :
"",
629 (do_code_backtrace && error->backtrace) ? error->backtrace->len : 0,
630 (do_code_backtrace && error->backtrace) ? (
char *)error->backtrace->s :
""
644 if (error->contextual && error->contextual->source_location)
653 (error->contextual && error->contextual->value_offset != 0) ?
" +" :
"",
654 (error->contextual && error->contextual->value_offset != 0)
655 ? error->contextual->value_offset
689 if (rv < 0)
goto return_rv;
690 rv = fprintf(fp,
"error type #: %d\n", error->code);
691 if (rv < 0)
goto return_rv;
693 if (rv < 0)
goto return_rv;
694 if (error->rv_source_id_z) {
695 rv = fprintf(fp,
"rv source: %s\n", error->rv_source_id_z);
696 if (rv < 0)
goto return_rv;
699 rv = fprintf(fp,
"rv: %d\n", error->rv);
700 if (rv < 0)
goto return_rv;
702 if (error->rv_decoded_z) {
703 rv = fprintf(fp,
"rv decoded: %s\n", error->rv_decoded_z);
704 if (rv < 0)
goto return_rv;
706 rv = fprintf(fp,
"message: %s\n", error->message_z);
707 if (rv < 0)
goto return_rv;
710 if (error->recursive_error) {
711 if (error->recursive_error_in_finally) {
712 rv = fprintf(fp,
"recursive error: in finally\n");
715 rv = fprintf(fp,
"recursive error: in catch\n");
717 if (rv < 0)
goto return_rv;
720 if (error->contextual) {
721 afw_value_contextual_resolve_value_source(&value_source,
724 rv = fprintf(fp,
"\ncontextual:\n");
725 if (rv < 0)
goto return_rv;
726 if (error->contextual->source_location) {
729 if (rv < 0)
goto return_rv;
733 error->contextual->value_offset);
734 if (rv < 0)
goto return_rv;
736 if (value_source.len != 0) {
739 if (rv < 0)
goto return_rv;
742 end = c + (error->contextual->value_offset < value_source.len ?
743 error->contextual->value_offset : value_source.len);
756 if (rv < 0)
goto return_rv;
759 if (rv < 0)
goto return_rv;
764 if (error->parser_cursor > 0) {
767 if (rv < 0)
goto return_rv;
770 if (error->backtrace) {
773 if (rv < 0)
goto return_rv;
793 if (rv < 0)
return rv;
796 xctx->env->flag_index_response_error_backtraceEvaluation,
799 backtraceExpression = impl_evaluation_backtrace(error, p, xctx);
800 if (backtraceExpression && backtraceExpression->len > 0) {
801 rv = fprintf(fp,
"evaluation backtrace:\n");
802 if (rv < 0)
return rv;
803 rv = (int)fwrite(backtraceExpression->s, 1, backtraceExpression->len,
826 &afw_s_sourceLocation,
830 afw_value_contextual_resolve_value_source(&value_source, contextual);
831 if (value_source.len > 0) {
837 end = c + (contextual->
value_offset < value_source.len ?
852 &afw_s_line, line, xctx);
873 if (error->contextual) {
874 impl_add_contextual(
object, error->contextual,
880 xctx->env->flag_index_response_error_contextual, xctx))
882 if (error->contextual) {
883 impl_add_contextual(
object, error->contextual,
896 if (error->backtrace &&
898 xctx->env->flag_index_response_error_backtrace, xctx))
901 &afw_s_backtrace, error->backtrace, xctx);
906 xctx->env->flag_index_response_error_backtraceEvaluation, xctx))
908 evaluation_backtrace = impl_evaluation_backtrace(error, p, xctx);
909 if (evaluation_backtrace) {
911 &afw_s_backtraceEvaluation, evaluation_backtrace, xctx);
921 &afw_s_errorCode, error->code, xctx);
925 if (error->parser_source) {
931 &afw_s_parserSource, error->parser_source, xctx);
933 &source_line, &source_column,
934 error->parser_source, error->parser_cursor, 4, xctx);
936 &afw_s_parserLineNumber, source_line, xctx);
938 &afw_s_parserColumnNumber, source_column, xctx);
941 else if (error->parser_cursor > 0) {
954 if (error->rv_source_id_z) {
964 &afw_s_rv, error->rv, xctx);
967 if (error->rv_decoded_z) {
981 if (error->recursive_error) {
983 &afw_s_recursiveError,
984 (error->recursive_error_in_finally)
985 ? &afw_s_a_in_finally
992 &afw_s_xctxUUID, xctx->uuid, xctx);
1015 vsnprintf((
char *)&(xctx->error->message_wa[0]),
1016 sizeof(xctx->error->message_wa), (
const char *)format, ap);
1018 return &(xctx->error->message_wa[0]);
1028 va_start(ap, format);
1030 vsnprintf((
char *)&(xctx->error->message_wa[0]),
1031 sizeof(xctx->error->message_wa), (
const char *)format, ap);
1035 return &(xctx->error->message_wa[0]);
1047 if (error->code <
sizeof(impl_error_code_map)
1051 result = &impl_error_code_map[error->code].html_description;
1054 if (!result) result = &impl_s_a_html_unknown;
1068 if (error->code <
sizeof(impl_error_code_map)
1072 result = impl_error_code_map[error->code].id.s;
1075 if (!result) result =
"unknown";
1086 return impl_error_code_map[code].error_allow_in_response;
AFW_DEFINE(const afw_object_t *)
#define AFW_DEFINE_ELLIPSIS(type)
Define a public afw function with variable arguments.
#define AFW_DECLARE(type)
Declare a public afw function.
Adaptive Framework Core Internal.
afw_object_set_property_as_integer(const afw_object_t *object, const afw_utf8_t *property_name, afw_integer_t internal, afw_xctx_t *xctx)
Set property function for data type integer values.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
#define AFW_UTF8_Z_LEN
String is NUL (0) terminate.
#define AFW_UTF8_LITERAL(A_STRING)
String literal initializer.
#define AFW_SIZE_T_MAX_BUFFER
this is the maximum number of digits that can be produced by afw_size_t plus null terminator.
#define AFW_INTEGER_FMT
Format string specifier used for afw_integer_t.
enum afw_error_code_e afw_error_code_t
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
apr_size_t afw_size_t
size_t.
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
enum afw_log_priority_e afw_log_priority_t
Log levels. See afw_log.h for more information.
#define AFW_ERROR_CODE_MAP(XX)
Error code map. IMPORTANT>>> Do not change the order of these entries. The order must match the order...
#define AFW_INTEGER_MAX_BUFFER
this is the maximum number of digits that can be produced by afw_integer_t plus negative sign plus nu...
apr_int64_t afw_integer_t
typedef for big signed int.
const afw_utf8_z_t *(* afw_environment_error_rv_decoder_z_t)(int rv, afw_utf8_z_t *wa, afw_size_t wa_size)
Typedef for error rv decoder functions.
afw_environment_error_rv_decoder_z_t afw_environment_get_error_rv_decoder(const afw_utf8_t *rv_source_id, afw_xctx_t *xctx)
Get the error rv decoder function associated with rv_source_id.
afw_error_http_status(const afw_error_t *error)
Returns http status for error.
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.
afw_error_print(FILE *fp, const afw_error_t *error)
Print error.
afw_error_write_log(afw_log_priority_t priority, const afw_error_t *error, afw_xctx_t *xctx)
Write error to environment log.
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.
afw_error_message(afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Build message in xctx error message_wa and return pointer.
afw_error_to_utf8(const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Convert error to utf8.
#define afw_error_source_file(error)
Returns value of error->source_z after last '/ 'or '\'.
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.
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.
#define afw_flag_is_active(flag_index, xctx)
Determine if flag for flag index is set in xctx.
#define afw_log_write(instance, priority, source_z, message, xctx)
Call method write of interface afw_log.
void afw_log_write_fz(const afw_log_t *instance, afw_log_priority_t priority, const afw_utf8_z_t *source_z, afw_xctx_t *xctx, const afw_utf8_z_t *format_z,...)
Log an message using a printf style format and parameters.
afw_number_bytes_needed_size_t(afw_size_t i)
Determine bytes needed to hold printable size_t.
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
const afw_utf8_t * afw_os_backtrace(afw_error_code_t code, int max_backtrace, afw_xctx_t *xctx)
Provide a backtrace if possible.
#define afw_stack_is_empty(instance)
Determine is a stack is empty.
void afw_utf8_writer_current_string(const afw_writer_t *writer, afw_utf8_t *current_string, afw_xctx_t *xctx)
Get the current string in a UTF-8 writer.
#define afw_utf8_create_copy(s, len, p, xctx)
Make a utf-8 sting from chars in pool specified.
afw_utf8_line_column_of_offset(afw_size_t *line_number, afw_size_t *column_number, const afw_utf8_t *s, afw_size_t offset, int tab_size, afw_xctx_t *xctx)
Determine the line and column of an offset in a string.
afw_utf8_line_count_and_max_column(afw_size_t *number_of_lines, afw_size_t *max_column_number, const afw_utf8_t *s, int tab_size, afw_xctx_t *xctx)
Determine the line count and maximum column in a string.
const afw_writer_t * afw_utf8_writer_create(const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Create UTF-8 writer.
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
#define afw_utf8_create(s, len, p, xctx)
Create utf-8 string without copy unless necessary in pool specified.
#define afw_value_get_info(instance, info, p, xctx)
Call method get_info of interface afw_value.
afw_value_true
Adaptive value true.
#define afw_writer_write(instance, buffer, size, xctx)
Call method write of interface afw_writer.
#define afw_writer_release(instance, xctx)
Call method release of interface afw_writer.
#define afw_writer_write_eol(instance, xctx)
Call method write_eol of interface afw_writer.
#define afw_writer_write_z(writer, s_z, xctx)
Call afw_writer_write() with zero terminated string.
#define afw_writer_write_utf8(writer, S, xctx)
Call afw_writer_write() with a afw_utf8_t string.
Contextual information provided in some values.
afw_size_t value_size
Size in full_source of value source.
const afw_utf8_t * source_location
Source location.
const afw_value_compiled_value_t * compiled_value
Compiled value this value is part of.
afw_size_t value_offset
Offset in full source of compiled value to this value.
Adaptive Framework Error.
afw_error_code_t code
Error code.
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.
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_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.
Filled in by afw_value get_info method.
const afw_utf8_t * full_source_type
The type of the full source.
const afw_utf8_t * full_source
The full source that was compiled.
Interface afw_writer public struct.
Interface afw_xctx public struct.