sqlite: handle thrown errors in result callback

This commit updates the aggregate function 'result' callback
handling to not crash when an exception is thrown.

Fixes: https://github.com/nodejs/node/issues/58425
PR-URL: https://github.com/nodejs/node/pull/58426
Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
Colin Ihrig 2025-05-25 17:49:37 -04:00 committed by GitHub
parent ab68ad031a
commit e201299011
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View File

@ -375,7 +375,10 @@ class CustomAggregate {
result = Local<Value>::New(isolate, agg->value);
}
JSValueToSQLiteResult(isolate, ctx, result);
if (!result.IsEmpty()) {
JSValueToSQLiteResult(isolate, ctx, result);
}
if (is_final) {
DestroyAggregateData(ctx);
}

View File

@ -309,6 +309,27 @@ describe('step', () => {
});
describe('result', () => {
test('throws if result throws an error', (t) => {
const db = new DatabaseSync(':memory:');
t.after(() => db.close());
db.exec('CREATE TABLE data (value INTEGER)');
db.exec('INSERT INTO data VALUES (1), (2), (3)');
db.aggregate('sum_int', {
start: 0,
step: (acc, value) => {
return acc + value;
},
result: () => {
throw new Error('result error');
},
});
t.assert.throws(() => {
db.prepare('SELECT sum_int(value) as result FROM data').get();
}, {
message: 'result error'
});
});
test('executes once when options.inverse is not present', (t) => {
const db = new DatabaseSync(':memory:');
t.after(() => db.close());