Skip to content

fix: report the message of Errors thrown in user-defined functions - #640

Merged
lovasoa merged 1 commit into
sql-js:masterfrom
ybai08:fix/function-error-object-message
Oct 19, 2026
Merged

lovasoa merged 1 commit into
sql-js:masterfrom
ybai08:fix/function-error-object-message

Conversation

@ybai08

@ybai08 ybai08 commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

When a function registered with create_function, or the step / finalize function of a create_aggregate aggregate, throws an Error object, the error is passed as-is to sqlite3_result_error, whose cwrap wrapper takes a "string". The Error is converted to an empty string, so the query fails with an empty message:

db.create_function("boom", () => { throw new Error("kaboom"); });
db.exec("SELECT boom()"); // throws Error with message "" (expected "kaboom")

In the debug builds the same call fails with an Emscripten assertion abort instead: Aborted(Assertion failed: stringToUTF8Array expects a string (got object)). This also happens when an aggregate's finalize hits a TypeError. Only thrown strings were reported correctly (which is what the existing tests use).

All three call sites now go through a small setFunctionError helper that passes error.message for Error objects and String(error) for any other thrown value. Thrown strings are reported exactly as before.

Tests: added cases to test/test_functions.js (a function throwing an Error, then a check that functions still work afterwards) and test/test_aggregate_functions.js (an Error thrown from step and from finalize).

Testing note: Emscripten is not installed on the machine this was prepared on, so the bundles were not rebuilt with npm run build. Instead, the src/api.js text inside the published 1.15.0 debug bundles (sql-wasm-debug.js, sql-wasm-inline-debug.js; identical to src/api.js at 2824d38) was replaced with the patched file, and the test runner was run against those:

  • before the fix: node test/all.js wasm and node test/all.js wasm-debug -> FAIL test aggregate_functions ("Reports the message of an Error thrown in a step function") and FAIL test functions ("Reports the message of a thrown Error"), Passed:23 Failed:2
  • after the fix: node test/all.js wasm-debug and node test/all.js wasm-inline-debug -> Passed:25 Failed:0
  • npx eslint . passes; node test/builds.js passes

The optimized wasm, wasm-browser and wasm-inline bundles were not rebuilt, so the full npm test was not run with the change.

When a function registered with create_function, or the step or
finalize function of an aggregate, threw an Error object, the error was
passed as-is to sqlite3_result_error, which is wrapped to take a string.
The Error was converted to an empty string, so the query failed with an
empty message, and debug builds aborted with "stringToUTF8Array expects
a string (got object)". Only thrown strings were reported correctly.

Pass the message of Error objects, and the string conversion of any
other thrown value, to sqlite3_result_error.

@lovasoa lovasoa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds reasonable, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants