diff --git a/src/api.js b/src/api.js index 47d64ef1..e391305c 100644 --- a/src/api.js +++ b/src/api.js @@ -1245,6 +1245,12 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { sqlite3_result_null(cx); } }; + var setFunctionError = function setFunctionError(cx, error) { + // sqlite3_result_error takes a string: passing an Error object + // directly would report an empty message + var message = error instanceof Error ? error.message : String(error); + sqlite3_result_error(cx, message, -1); + }; /** Register a custom function with SQLite @example Register a simple function @@ -1266,7 +1272,7 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { try { result = func.apply(null, args); } catch (error) { - sqlite3_result_error(cx, error, -1); + setFunctionError(cx, error); return; } setFunctionResult(cx, result); @@ -1367,7 +1373,7 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { state[p] = step.apply(null, mergedArgs); } catch (error) { delete state[p]; - sqlite3_result_error(cx, error, -1); + setFunctionError(cx, error); } } @@ -1378,7 +1384,7 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { result = finalize(state[p]); } catch (error) { delete state[p]; - sqlite3_result_error(cx, error, -1); + setFunctionError(cx, error); return; } setFunctionResult(cx, result); diff --git a/test/test_aggregate_functions.js b/test/test_aggregate_functions.js index d28c775f..bcbbdb9d 100644 --- a/test/test_aggregate_functions.js +++ b/test/test_aggregate_functions.js @@ -99,6 +99,25 @@ exports.test = function (SQL, assert) { 3, "Aggregate functions work after an exception has been thrown in finalize" ); + + db.create_aggregate("throws_error_step", { + step: (state, value) => { throw new Error("step error object"); }, + }); + assert.throws( + () => db.exec("SELECT throws_error_step(column1) FROM (VALUES (1));"), + /step error object/, + "Reports the message of an Error thrown in a step function" + ); + + db.create_aggregate("throws_error_finalize", { + step: (state, value) => value, + finalize: (state) => { throw new Error("finalize error object"); }, + }); + assert.throws( + () => db.exec("SELECT throws_error_finalize(column1) FROM (VALUES (1));"), + /finalize error object/, + "Reports the message of an Error thrown in a finalize function" + ); } // helper function to calculate a percentile from an array. Will modify the diff --git a/test/test_functions.js b/test/test_functions.js index eb1cc2a8..c0b17193 100644 --- a/test/test_functions.js +++ b/test/test_functions.js @@ -149,7 +149,11 @@ exports.test = function(SQL, assert){ db.create_function("throwFunction", function () { throw "internal exception"; return 5;} ); assert.throws(function(){db.exec("SELECT throwFunction()");},/internal exception/, "Can handle internal exceptions"); - + + db.create_function("throwErrorFunction", function () { throw new Error("internal error object"); }); + assert.throws(function(){db.exec("SELECT throwErrorFunction()");},/internal error object/, "Reports the message of a thrown Error"); + assert.equal(db.exec("SELECT addOne(1);")[0]["values"][0][0], 2, "Functions work after an Error has been thrown"); + db.create_function("customeObjectFunction", function () { return {test:123};} ); assert.throws(function(){db.exec("SELECT customeObjectFunction()");},/Wrong API use/, "Reports wrong API use");