Consolidate error handling until util, too.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3682 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2021-11-03 22:28:25 +00:00
parent fde7fb4270
commit 2fb7fceb0c
6 changed files with 81 additions and 92 deletions

View File

@ -160,34 +160,6 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in
return result; return result;
} }
static void _check_call(JSContext* context, JSValue result)
{
if (JS_IsError(context, result))
{
const char* value = JS_ToCString(context, result);
printf("ERROR: %s\n", value);
JS_FreeCString(context, value);
JSValue stack = JS_GetPropertyStr(context, result, "stack");
if (!JS_IsUndefined(stack))
{
const char* stack_str = JS_ToCString(context, stack);
printf("%s\n", stack_str);
JS_FreeCString(context, stack_str);
}
JS_FreeValue(context, stack);
}
else if (JS_IsException(result))
{
js_std_dump_error(context);
JSValue error = JS_GetException(context);
const char* value = JS_ToCString(context, error);
printf("Exception: %s\n", value);
JS_FreeCString(context, value);
JS_FreeValue(context, error);
abort();
}
}
typedef struct _sqlStream_callback_t typedef struct _sqlStream_callback_t
{ {
JSContext* context; JSContext* context;
@ -198,7 +170,7 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data)
{ {
sqlStream_callback_t* info = user_data; sqlStream_callback_t* info = user_data;
JSValue response = JS_Call(info->context, info->callback, JS_UNDEFINED, 1, &row); JSValue response = JS_Call(info->context, info->callback, JS_UNDEFINED, 1, &row);
_check_call(info->context, response); tf_util_report_error(info->context, response);
JS_FreeValue(info->context, response); JS_FreeValue(info->context, response);
if (tf_task_get(info->context)) if (tf_task_get(info->context))
{ {
@ -214,7 +186,7 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data)
if (context) if (context)
{ {
JSValue result = JS_GetException(context); JSValue result = JS_GetException(context);
_check_call(context, result); tf_util_report_error(context, result);
} }
if (r < 0) if (r < 0)
{ {
@ -373,7 +345,7 @@ static void _tf_ssb_call_callback(tf_ssb_t* ssb, const char* name, void* user_da
{ {
JSValue args = JS_UNDEFINED; JSValue args = JS_UNDEFINED;
JSValue response = JS_Call(context, callback, JS_UNDEFINED, 0, &args); JSValue response = JS_Call(context, callback, JS_UNDEFINED, 0, &args);
_check_call(context, response); tf_util_report_error(context, response);
if (tf_task_get(context)) if (tf_task_get(context))
{ {
tf_task_run_jobs(tf_task_get(context)); tf_task_run_jobs(tf_task_get(context));
@ -463,7 +435,7 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ
JS_SetPropertyStr(context, object, "send_binary", JS_NewCFunction(context, _tf_ssb_rpc_send_binary, "send_binary", 1)); JS_SetPropertyStr(context, object, "send_binary", JS_NewCFunction(context, _tf_ssb_rpc_send_binary, "send_binary", 1));
JSValue result = JS_Call(context, callback, JS_UNDEFINED, 1, &object); JSValue result = JS_Call(context, callback, JS_UNDEFINED, 1, &object);
_check_call(context, result); tf_util_report_error(context, result);
JS_FreeValue(context, result); JS_FreeValue(context, result);
JS_FreeValue(context, object); JS_FreeValue(context, object);
} }
@ -521,7 +493,7 @@ static void _tf_ssb_on_blob_want_added(tf_ssb_t* ssb, const char* id, void* user
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data); JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
JSValue string = JS_NewString(context, id); JSValue string = JS_NewString(context, id);
JSValue response = JS_Call(context, callback, JS_UNDEFINED, 1, &string); JSValue response = JS_Call(context, callback, JS_UNDEFINED, 1, &string);
_check_call(context, response); tf_util_report_error(context, response);
JS_FreeValue(context, response); JS_FreeValue(context, response);
JS_FreeValue(context, string); JS_FreeValue(context, string);
} }
@ -562,7 +534,7 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch
}; };
printf("calling function for ptr %p IsFunction=%d\n", user_data, JS_IsFunction(context, callback)); printf("calling function for ptr %p IsFunction=%d\n", user_data, JS_IsFunction(context, callback));
response = JS_Call(context, callback, JS_UNDEFINED, 2, args); response = JS_Call(context, callback, JS_UNDEFINED, 2, args);
_check_call(context, response); tf_util_report_error(context, response);
JS_FreeValue(context, args[0]); JS_FreeValue(context, args[0]);
JS_FreeValue(context, object); JS_FreeValue(context, object);
} }
@ -576,7 +548,7 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch
object, object,
}; };
response = JS_Call(context, callback, JS_UNDEFINED, 2, args); response = JS_Call(context, callback, JS_UNDEFINED, 2, args);
_check_call(context, response); tf_util_report_error(context, response);
JS_FreeValue(context, args[0]); JS_FreeValue(context, args[0]);
JS_FreeValue(context, object); JS_FreeValue(context, object);
} }
@ -649,7 +621,7 @@ void tf_ssb_run_file(JSContext* context, const char* file_name)
JSContext* context2 = NULL; JSContext* context2 = NULL;
int r = JS_ExecutePendingJob(runtime, &context2); int r = JS_ExecutePendingJob(runtime, &context2);
JSValue result = JS_GetException(context2); JSValue result = JS_GetException(context2);
_check_call(context, result); tf_util_report_error(context, result);
if (r == 0) if (r == 0)
{ {
break; break;

View File

@ -247,9 +247,9 @@ static void _export_record_release_for_task(tf_task_t* task, taskid_t task_id)
} }
} }
static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error) void tf_task_send_error_to_parent(tf_task_t* task, JSValue error)
{ {
if (task->_parent) if (task && task->_parent)
{ {
void* buffer = NULL; void* buffer = NULL;
size_t size = 0; size_t size = 0;
@ -259,36 +259,6 @@ static void _tf_task_send_error_to_parent(tf_task_t* task, JSValue error)
} }
} }
void tf_task_report_error(tf_task_t* task, JSValue error)
{
JSContext* context = task->_context;
if (JS_IsError(context, error))
{
const char* value = JS_ToCString(context, error);
printf("ERROR: %s\n", value);
JS_FreeCString(context, value);
JSValue stack = JS_GetPropertyStr(context, error, "stack");
if (!JS_IsUndefined(stack))
{
const char* stack_str = JS_ToCString(context, stack);
printf("%s\n", stack_str);
JS_FreeCString(context, stack_str);
}
JS_FreeValue(context, stack);
_tf_task_send_error_to_parent(task, error);
}
else if (JS_IsException(error))
{
error = JS_GetException(context);
const char* value = JS_ToCString(context, error);
printf("Exception: %s\n", value);
JS_FreeCString(context, value);
_tf_task_send_error_to_parent(task, error);
}
}
static const char* _task_loadFile(const char* fileName) static const char* _task_loadFile(const char* fileName)
{ {
char* result = NULL; char* result = NULL;
@ -348,7 +318,7 @@ static void _task_timeoutCallback(uv_timer_t* handle)
JS_NULL, JS_NULL,
0, 0,
NULL); NULL);
tf_task_report_error(timeout->_task, result); tf_util_report_error(timeout->_task->_context, result);
JS_FreeValue(timeout->_task->_context, result); JS_FreeValue(timeout->_task->_context, result);
tf_task_run_jobs(timeout->_task); tf_task_run_jobs(timeout->_task);
tf_trace_end(timeout->_task->_trace); tf_trace_end(timeout->_task->_trace);
@ -394,7 +364,7 @@ int tf_task_execute(tf_task_t* task, const char* fileName)
if (source) if (source)
{ {
JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, 0); JSValue result = JS_Eval(task->_context, source, strlen(source), fileName, 0);
tf_task_report_error(task, result); tf_util_report_error(task->_context, result);
if (!JS_IsError(task->_context, result) && !JS_IsException(result)) if (!JS_IsError(task->_context, result) && !JS_IsException(result))
{ {
executed = true; executed = true;
@ -514,7 +484,7 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid
} }
result = JS_Call(to->_context, function, this_val, length - 1, argument_array); result = JS_Call(to->_context, function, this_val, length - 1, argument_array);
tf_trace_end(to->_trace); tf_trace_end(to->_trace);
tf_task_report_error(to, result); tf_util_report_error(to->_context, result);
tf_task_run_jobs(to); tf_task_run_jobs(to);
} }
else else
@ -563,10 +533,10 @@ static void _forward_promise(tf_task_t* from, tf_taskstub_t* to, promiseid_t pro
JSValue catch_handler = JS_NewCFunctionData(from->_context, _invokeCatch, 0, 0, 2, data); JSValue catch_handler = JS_NewCFunctionData(from->_context, _invokeCatch, 0, 0, 2, data);
JSValue error = JS_Call(from->_context, promise_then, result, 1, &then_handler); JSValue error = JS_Call(from->_context, promise_then, result, 1, &then_handler);
tf_task_report_error(from, error); tf_util_report_error(from->_context, error);
JS_FreeValue(from->_context, error); JS_FreeValue(from->_context, error);
error = JS_Call(from->_context, promise_catch, result, 1, &catch_handler); error = JS_Call(from->_context, promise_catch, result, 1, &catch_handler);
tf_task_report_error(from, error); tf_util_report_error(from->_context, error);
JS_FreeValue(from->_context, error); JS_FreeValue(from->_context, error);
tf_task_run_jobs(from); tf_task_run_jobs(from);
@ -971,7 +941,7 @@ JSValue _tf_task_require(JSContext* context, JSValueConst this_val, int argc, JS
JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports"); JSValue oldExports = JS_GetPropertyStr(task->_context, global, "exports");
JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, exports)); JS_SetPropertyStr(task->_context, global, "exports", JS_DupValue(task->_context, exports));
JSValue eval = JS_Eval(task->_context, source, strlen(source), path, 0); JSValue eval = JS_Eval(task->_context, source, strlen(source), path, 0);
tf_task_report_error(task, eval); tf_util_report_error(task->_context, eval);
tf_task_run_jobs(task); tf_task_run_jobs(task);
if (JS_IsError(task->_context, eval) || if (JS_IsError(task->_context, eval) ||
JS_IsException(eval)) JS_IsException(eval))
@ -1008,7 +978,7 @@ static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const
{ {
tf_trace_begin(task->_trace, "_tf_task_executeSource"); tf_trace_begin(task->_trace, "_tf_task_executeSource");
JSValue result = JS_Eval(task->_context, source, strlen(source), name, 0); JSValue result = JS_Eval(task->_context, source, strlen(source), name, 0);
tf_task_report_error(task, result); tf_util_report_error(task->_context, result);
if (!*task->_scriptName) if (!*task->_scriptName)
{ {
snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name); snprintf(task->_scriptName, sizeof(task->_scriptName), "%s", name);
@ -1046,7 +1016,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int
JSValue oldExports = JS_GetPropertyStr(context, global, "exports"); JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports)); JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports));
JSValue result = JS_Eval(context, source, length, name, 0); JSValue result = JS_Eval(context, source, length, name, 0);
tf_task_report_error(task, result); tf_util_report_error(context, result);
JS_SetPropertyStr(context, global, "exports", oldExports); JS_SetPropertyStr(context, global, "exports", oldExports);
JS_FreeValue(context, global); JS_FreeValue(context, global);
tf_task_run_jobs(task); tf_task_run_jobs(task);
@ -1061,7 +1031,7 @@ JSValue _tf_task_sandbox_require(JSContext* context, JSValueConst this_val, int
JSValue oldExports = JS_GetPropertyStr(context, global, "exports"); JSValue oldExports = JS_GetPropertyStr(context, global, "exports");
JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports)); JS_SetPropertyStr(context, global, "exports", JS_DupValue(context, exports));
JSValue result = JS_Eval(context, source, length, name, 0); JSValue result = JS_Eval(context, source, length, name, 0);
tf_task_report_error(task, result); tf_util_report_error(context, result);
JS_SetPropertyStr(context, global, "exports", oldExports); JS_SetPropertyStr(context, global, "exports", oldExports);
JS_FreeValue(context, global); JS_FreeValue(context, global);
tf_task_run_jobs(task); tf_task_run_jobs(task);
@ -1142,7 +1112,7 @@ void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value
if (it) if (it)
{ {
JSValue result = JS_Call(task->_context, it->values[1], JS_UNDEFINED, 1, &value); JSValue result = JS_Call(task->_context, it->values[1], JS_UNDEFINED, 1, &value);
tf_task_report_error(task, result); tf_util_report_error(task->_context, result);
JS_FreeValue(task->_context, it->values[1]); JS_FreeValue(task->_context, it->values[1]);
JS_FreeValue(task->_context, it->values[2]); JS_FreeValue(task->_context, it->values[2]);
JS_FreeValue(task->_context, result); JS_FreeValue(task->_context, result);
@ -1162,7 +1132,7 @@ void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value)
if (it) if (it)
{ {
JSValue result = JS_Call(task->_context, it->values[2], JS_UNDEFINED, 1, &value); JSValue result = JS_Call(task->_context, it->values[2], JS_UNDEFINED, 1, &value);
tf_task_report_error(task, result); tf_util_report_error(task->_context, result);
JS_FreeValue(task->_context, it->values[1]); JS_FreeValue(task->_context, it->values[1]);
JS_FreeValue(task->_context, it->values[2]); JS_FreeValue(task->_context, it->values[2]);
JS_FreeValue(task->_context, result); JS_FreeValue(task->_context, result);
@ -1239,10 +1209,9 @@ static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFun
static void _tf_task_promise_rejection_tracker(JSContext* context, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* user_data) static void _tf_task_promise_rejection_tracker(JSContext* context, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* user_data)
{ {
tf_task_t* task = user_data;
if (!is_handled) if (!is_handled)
{ {
tf_task_report_error(task, reason); tf_util_report_error(context, reason);
} }
} }
@ -1448,7 +1417,10 @@ void tf_task_run_jobs(tf_task_t* task)
JSContext* context = NULL; JSContext* context = NULL;
int r = JS_ExecutePendingJob(task->_runtime, &context); int r = JS_ExecutePendingJob(task->_runtime, &context);
JSValue result = JS_GetException(context); JSValue result = JS_GetException(context);
tf_task_report_error(task, result); if (context)
{
tf_util_report_error(context, result);
}
if (r < 0) if (r < 0)
{ {
js_std_dump_error(context); js_std_dump_error(context);

View File

@ -67,3 +67,5 @@ void tf_task_report_error(tf_task_t* task, JSValue error);
JSValue tf_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element); JSValue tf_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element);
uint8_t *tf_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj); uint8_t *tf_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj);
void tf_task_send_error_to_parent(tf_task_t* task, JSValue error);

View File

@ -3,6 +3,7 @@
#include "packetstream.h" #include "packetstream.h"
#include "serialize.h" #include "serialize.h"
#include "task.h" #include "task.h"
#include "util.js.h"
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
@ -269,7 +270,7 @@ static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int
{ {
JSValue argv[] = { JS_NewInt32(context, status), JS_NewInt32(context, terminationSignal) }; JSValue argv[] = { JS_NewInt32(context, status), JS_NewInt32(context, terminationSignal) };
JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv); JSValue result = JS_Call(context, stub->_on_exit, JS_NULL, 2, argv);
tf_task_report_error(stub->_owner, result); tf_util_report_error(context, result);
JS_FreeValue(context, result); JS_FreeValue(context, result);
tf_task_run_jobs(stub->_owner); tf_task_run_jobs(stub->_owner);
JS_FreeValue(context, argv[0]); JS_FreeValue(context, argv[0]);
@ -393,7 +394,7 @@ void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error)
if (!JS_IsUndefined(stub->_on_error)) if (!JS_IsUndefined(stub->_on_error))
{ {
JSValue result = JS_Call(context, stub->_on_error, JS_NULL, 1, &error); JSValue result = JS_Call(context, stub->_on_error, JS_NULL, 1, &error);
tf_task_report_error(stub->_owner, result); tf_util_report_error(context, result);
JS_FreeValue(context, result); JS_FreeValue(context, result);
tf_task_run_jobs(stub->_owner); tf_task_run_jobs(stub->_owner);
} }

View File

@ -2,6 +2,8 @@
#include "task.h" #include "task.h"
#include "quickjs-libc.h"
static JSValue _util_utf8_decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) static JSValue _util_utf8_decode(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{ {
JSValue result = JS_NULL; JSValue result = JS_NULL;
@ -42,17 +44,17 @@ JSValue tf_util_utf8_decode(JSContext* context, JSValue value)
return _util_utf8_decode(context, JS_NULL, 1, &value); return _util_utf8_decode(context, JS_NULL, 1, &value);
} }
uint8_t* tf_util_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj) uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj)
{ {
uint8_t* result = JS_GetArrayBuffer(ctx, psize, obj); uint8_t* result = JS_GetArrayBuffer(context, psize, obj);
JS_FreeValue(ctx, JS_GetException(ctx)); JS_FreeValue(context, JS_GetException(context));
return result; return result;
} }
JSValue tf_util_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element) JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element)
{ {
JSValue result = JS_GetTypedArrayBuffer(ctx, obj, pbyte_offset, pbyte_length, pbytes_per_element); JSValue result = JS_GetTypedArrayBuffer(context, obj, pbyte_offset, pbyte_length, pbytes_per_element);
JS_FreeValue(ctx, JS_GetException(ctx)); JS_FreeValue(context, JS_GetException(context));
return result; return result;
} }
@ -80,6 +82,45 @@ JSValue _util_print(JSContext* context, JSValueConst this_val, int argc, JSValue
return JS_NULL; return JS_NULL;
} }
void tf_util_report_error(JSContext* context, JSValue value)
{
if (JS_IsError(context, value))
{
const char* string = JS_ToCString(context, value);
printf("ERROR: %s\n", string);
JS_FreeCString(context, string);
JSValue stack = JS_GetPropertyStr(context, value, "stack");
if (!JS_IsUndefined(stack))
{
const char* stack_str = JS_ToCString(context, stack);
printf("%s\n", stack_str);
JS_FreeCString(context, stack_str);
}
JS_FreeValue(context, stack);
tf_task_t* task = tf_task_get(context);
if (task)
{
tf_task_send_error_to_parent(task, value);
}
}
else if (JS_IsException(value))
{
js_std_dump_error(context);
JSValue exception = JS_GetException(context);
const char* string = JS_ToCString(context, exception);
printf("Exception: %s\n", string);
JS_FreeCString(context, string);
tf_task_t* task = tf_task_get(context);
if (task)
{
tf_task_send_error_to_parent(task, exception);
}
JS_FreeValue(context, exception);
}
}
void tf_util_register(JSContext* context) void tf_util_register(JSContext* context)
{ {
JSValue global = JS_GetGlobalObject(context); JSValue global = JS_GetGlobalObject(context);

View File

@ -4,5 +4,6 @@
void tf_util_register(JSContext* context); void tf_util_register(JSContext* context);
JSValue tf_util_utf8_decode(JSContext* context, JSValue value); JSValue tf_util_utf8_decode(JSContext* context, JSValue value);
uint8_t* tf_util_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj); uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj);
JSValue tf_util_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element); JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element);
void tf_util_report_error(JSContext* context, JSValue value);