Skip to content

Commit

Permalink
sqlite: handle exception thrown in conflict handler
Browse files Browse the repository at this point in the history
  • Loading branch information
louwers committed Dec 24, 2024
1 parent e6001b3 commit f63c3b4
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
2 changes: 2 additions & 0 deletions doc/api/sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ added:
`SQLITE_CHANGESET_DATA` or `SQLITE_CHANGESET_CONFLICT` conflicts).
* `SQLITE_CHANGESET_ABORT`: Abort on conflict and roll back the database.

When an error is thrown in the conflict handler, applying the changeset is aborted and the database is rolled back.

**Default**: A function that returns `SQLITE_CHANGESET_ABORT`.
* Returns: {boolean} Whether the changeset was applied succesfully without being aborted.

Expand Down
9 changes: 8 additions & 1 deletion src/node_sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "node_mem-inl.h"
#include "sqlite3.h"
#include "util-inl.h"
#include "v8-exception.h"

#include <cinttypes>

Expand Down Expand Up @@ -42,6 +43,7 @@ using v8::Number;
using v8::Object;
using v8::SideEffectType;
using v8::String;
using v8::TryCatch;
using v8::Uint8Array;
using v8::Value;

Expand Down Expand Up @@ -795,9 +797,14 @@ void DatabaseSync::ApplyChangeset(const FunctionCallbackInfo<Value>& args) {
Local<Function> conflictFunc = conflictValue.As<Function>();
conflictCallback = [env, conflictFunc](int conflictType) -> int {
Local<Value> argv[] = {Integer::New(env->isolate(), conflictType)};
TryCatch try_catch(env->isolate());
Local<Value> result =
conflictFunc->Call(env->context(), Null(env->isolate()), 1, argv)
.ToLocalChecked();
.FromMaybe(Local<Value>());
if (try_catch.HasCaught()) {
try_catch.ReThrow();
return SQLITE_CHANGESET_ABORT;
}
return result->Int32Value(env->context()).FromJust();
};
}
Expand Down
14 changes: 14 additions & 0 deletions test/parallel/test-sqlite-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ suite('conflict resolution', () => {
message: 'bad parameter or other API misuse'
});
});

test("conflict resolution handler throws", (t) => {

Check failure on line 340 in test/parallel/test-sqlite-session.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Strings must use singlequote
const { database2, changeset } = prepareConflict();
t.assert.throws(() => {
database2.applyChangeset(changeset, {
onConflict: () => {
throw new Error('some error');
}
});
}, {
name: 'Error',
message: 'some error'
});
});
});

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

0 comments on commit f63c3b4

Please sign in to comment.