Skip to content

Commit ab95309

Browse files
committed
sqlite: isolate applyChangeset filter errors
Track filter callback failures within each applyChangeset() invocation. Returning false from xFilter is not a SQLite error. This previously left the database-wide suppression flag set, which could hide the next unrelated SQLite error. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: codex:gpt-5.6-sol PR-URL: #64823 Fixes: #64822 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
1 parent d512d2d commit ab95309

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

src/node_sqlite.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,7 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
23262326

23272327
Local<Function> conflictFunc;
23282328
Local<Function> filterFunc;
2329+
bool filterCallbackFailed = false;
23292330
if (args.Length() > 1 && !args[1]->IsUndefined()) {
23302331
if (!args[1]->IsObject()) {
23312332
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
@@ -2387,25 +2388,25 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
23872388

23882389
filterFunc = filterValue.As<Function>();
23892390

2390-
context.filterCallback =
2391-
[env, db, &filterFunc](std::string_view item) -> bool {
2391+
context.filterCallback = [env, &filterFunc, &filterCallbackFailed](
2392+
std::string_view item) -> bool {
23922393
// If there was an error in the previous call to the filter's
23932394
// callback, we skip calling it again.
2394-
if (db->ignore_next_sqlite_error_) {
2395+
if (filterCallbackFailed) {
23952396
return false;
23962397
}
23972398

23982399
Local<Value> argv[1];
23992400
if (!ToV8Value(env->context(), item, env->isolate())
24002401
.ToLocal(&argv[0])) {
2401-
db->SetIgnoreNextSQLiteError(true);
2402+
filterCallbackFailed = true;
24022403
return false;
24032404
}
24042405

24052406
Local<Value> result;
24062407
if (!filterFunc->Call(env->context(), Null(env->isolate()), 1, argv)
24072408
.ToLocal(&result)) {
2408-
db->SetIgnoreNextSQLiteError(true);
2409+
filterCallbackFailed = true;
24092410
return false;
24102411
}
24112412

test/parallel/test-sqlite-session.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,13 @@ test('filter handler throws', (t) => {
404404
name: 'Error',
405405
message: 'Error filtering table data1'
406406
});
407+
408+
t.assert.throws(() => {
409+
database2.exec('CREATE TABLEEEE');
410+
}, {
411+
code: 'ERR_SQLITE_ERROR',
412+
message: /syntax error/,
413+
});
407414
});
408415

409416
test('database.createSession() - filter changes', (t) => {

0 commit comments

Comments
 (0)