Made sure that SQL errors make it to the client.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3867 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
11ad344e52
commit
804359d12e
@ -187,6 +187,36 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_
|
|||||||
fprintf(stderr, "Unable to store number.\n");
|
fprintf(stderr, "Unable to store number.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (JS_IsException(value))
|
||||||
|
{
|
||||||
|
JSValue exception = JS_GetException(context);
|
||||||
|
const char* message = JS_ToCString(context, exception);
|
||||||
|
|
||||||
|
JSValue error = JS_NewObject(context);
|
||||||
|
JS_SetPropertyStr(context, error, "message", JS_NewString(context, message ? message : "[exception]"));
|
||||||
|
|
||||||
|
if (JS_IsError(context, exception))
|
||||||
|
{
|
||||||
|
JSValue m = JS_GetPropertyStr(context, exception, "message");
|
||||||
|
if (!JS_IsUndefined(m) && !JS_IsException(m))
|
||||||
|
{
|
||||||
|
const char* ms = JS_ToCString(context, m);
|
||||||
|
JS_FreeCString(context, ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSValue stack = JS_GetPropertyStr(context, exception, "stack");
|
||||||
|
if (!JS_IsUndefined(stack) && !JS_IsException(stack))
|
||||||
|
{
|
||||||
|
JS_SetPropertyStr(context, error, "stack", JS_DupValue(context, stack));
|
||||||
|
}
|
||||||
|
JS_FreeValue(context, stack);
|
||||||
|
}
|
||||||
|
_serialize_writeInt32(buffer, kException);
|
||||||
|
_serialize_storeInternal(task, to, buffer, error, depth + 1);
|
||||||
|
JS_FreeCString(context, message);
|
||||||
|
JS_FreeValue(context, error);
|
||||||
|
JS_FreeValue(context, exception);
|
||||||
|
}
|
||||||
else if (JS_IsString(value))
|
else if (JS_IsString(value))
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@ -235,27 +265,6 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_
|
|||||||
exportid_t exportId = tf_task_export_function(task, to, value);
|
exportid_t exportId = tf_task_export_function(task, to, value);
|
||||||
_serialize_writeInt32(buffer, exportId);
|
_serialize_writeInt32(buffer, exportId);
|
||||||
}
|
}
|
||||||
else if (JS_IsException(value))
|
|
||||||
{
|
|
||||||
JSValue exception = JS_GetException(context);
|
|
||||||
JSValue error = JS_NewObject(context);
|
|
||||||
JSValue message = JS_GetPropertyStr(context, exception, "message");
|
|
||||||
if (!JS_IsException(message))
|
|
||||||
{
|
|
||||||
JS_SetPropertyStr(context, error, "message", message);
|
|
||||||
}
|
|
||||||
if (JS_IsError(context, exception))
|
|
||||||
{
|
|
||||||
JSValue stack = JS_GetPropertyStr(context, exception, "stack");
|
|
||||||
if (!JS_IsUndefined(stack))
|
|
||||||
{
|
|
||||||
JS_SetPropertyStr(context, error, "stack", JS_DupValue(context, stack));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_serialize_writeInt32(buffer, kException);
|
|
||||||
_serialize_storeInternal(task, to, buffer, error, depth + 1);
|
|
||||||
JS_FreeValue(context, error);
|
|
||||||
}
|
|
||||||
else if (JS_IsError(tf_task_get_context(task), value))
|
else if (JS_IsError(tf_task_get_context(task), value))
|
||||||
{
|
{
|
||||||
_serialize_writeInt32(buffer, kError);
|
_serialize_writeInt32(buffer, kError);
|
||||||
|
15
src/ssb.db.c
15
src/ssb.db.c
@ -526,17 +526,19 @@ static int _tf_ssb_sqlite_authorizer(void* user_data, int action_code, const cha
|
|||||||
return SQLITE_DENY;
|
return SQLITE_DENY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data)
|
JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data)
|
||||||
{
|
{
|
||||||
|
JSValue result = JS_UNDEFINED;
|
||||||
sqlite3* db = tf_ssb_get_db(ssb);
|
sqlite3* db = tf_ssb_get_db(ssb);
|
||||||
|
JSContext* context = tf_ssb_get_context(ssb);
|
||||||
sqlite3_stmt* statement;
|
sqlite3_stmt* statement;
|
||||||
sqlite3_set_authorizer(db, _tf_ssb_sqlite_authorizer, ssb);
|
sqlite3_set_authorizer(db, _tf_ssb_sqlite_authorizer, ssb);
|
||||||
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
|
if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
JSContext* context = tf_ssb_get_context(ssb);
|
|
||||||
if (_tf_ssb_sqlite_bind_json(context, db, statement, binds))
|
if (_tf_ssb_sqlite_bind_json(context, db, statement, binds))
|
||||||
{
|
{
|
||||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
int r = SQLITE_OK;
|
||||||
|
while ((r = sqlite3_step(statement)) == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
JSValue row = _tf_ssb_sqlite_row_to_json(context, statement);
|
JSValue row = _tf_ssb_sqlite_row_to_json(context, statement);
|
||||||
tf_trace_t* trace = tf_ssb_get_trace(ssb);
|
tf_trace_t* trace = tf_ssb_get_trace(ssb);
|
||||||
@ -545,14 +547,19 @@ void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds
|
|||||||
tf_trace_end(trace);
|
tf_trace_end(trace);
|
||||||
JS_FreeValue(context, row);
|
JS_FreeValue(context, row);
|
||||||
}
|
}
|
||||||
|
if (r != SQLITE_DONE)
|
||||||
|
{
|
||||||
|
result = JS_ThrowInternalError(context, "SQL Error %s: running \"%s\".", sqlite3_errmsg(db), query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sqlite3_finalize(statement);
|
sqlite3_finalize(statement);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("prepare failed: %s: %s\n", sqlite3_errmsg(db), query);
|
result = JS_ThrowInternalError(context, "SQL Error %s: preparing \"%s\".", sqlite3_errmsg(db), query);
|
||||||
}
|
}
|
||||||
sqlite3_set_authorizer(db, NULL, NULL);
|
sqlite3_set_authorizer(db, NULL, NULL);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue _tf_ssb_format_message(JSContext* context, const char* previous, const char* author, int64_t sequence, double timestamp, const char* hash, const char* content, const char* signature, bool sequence_before_author)
|
static JSValue _tf_ssb_format_message(JSContext* context, const char* previous, const char* author, int64_t sequence, double timestamp, const char* hash, const char* content, const char* signature, bool sequence_before_author)
|
||||||
|
@ -13,7 +13,7 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char*
|
|||||||
|
|
||||||
bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content);
|
bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content);
|
||||||
bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, int64_t* out_sequence, char* out_message_id, size_t out_message_id_size);
|
bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, int64_t* out_sequence, char* out_message_id, size_t out_message_id_size);
|
||||||
void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data);
|
JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data);
|
||||||
|
|
||||||
typedef struct sqlite3 sqlite3;
|
typedef struct sqlite3 sqlite3;
|
||||||
bool tf_ssb_db_check(sqlite3* db, const char* author);
|
bool tf_ssb_db_check(sqlite3* db, const char* author);
|
||||||
|
@ -177,21 +177,23 @@ static void _tf_ssb_sqlStream_callback(JSValue row, void* user_data)
|
|||||||
|
|
||||||
static JSValue _tf_ssb_sqlStream(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _tf_ssb_sqlStream(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
{
|
{
|
||||||
|
JSValue result = JS_NULL;
|
||||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||||
if (ssb)
|
if (ssb)
|
||||||
{
|
{
|
||||||
const char* query = JS_ToCString(context, argv[0]);
|
const char* query = JS_ToCString(context, argv[0]);
|
||||||
if (query)
|
if (query)
|
||||||
{
|
{
|
||||||
sqlStream_callback_t info = {
|
sqlStream_callback_t info =
|
||||||
|
{
|
||||||
.context = context,
|
.context = context,
|
||||||
.callback = argv[2],
|
.callback = argv[2],
|
||||||
};
|
};
|
||||||
tf_ssb_db_visit_query(ssb, query, argv[1], _tf_ssb_sqlStream_callback, &info);
|
result = tf_ssb_db_visit_query(ssb, query, argv[1], _tf_ssb_sqlStream_callback, &info);
|
||||||
JS_FreeCString(context, query);
|
JS_FreeCString(context, query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JS_NULL;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue _tf_ssb_post(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _tf_ssb_post(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
|
@ -1346,6 +1346,7 @@ static bool _tf_task_run_jobs(tf_task_t* task)
|
|||||||
if (context)
|
if (context)
|
||||||
{
|
{
|
||||||
tf_util_report_error(context, result);
|
tf_util_report_error(context, result);
|
||||||
|
JS_FreeValue(context, result);
|
||||||
}
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
|
@ -130,17 +130,15 @@ bool tf_util_report_error(JSContext* context, JSValue value)
|
|||||||
}
|
}
|
||||||
else if (JS_IsException(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);
|
tf_task_t* task = tf_task_get(context);
|
||||||
if (task)
|
if (task)
|
||||||
{
|
{
|
||||||
tf_task_send_error_to_parent(task, exception);
|
tf_task_send_error_to_parent(task, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
js_std_dump_error(context);
|
||||||
}
|
}
|
||||||
JS_FreeValue(context, exception);
|
|
||||||
is_error = true;
|
is_error = true;
|
||||||
}
|
}
|
||||||
return is_error;
|
return is_error;
|
||||||
|
Loading…
Reference in New Issue
Block a user