diff --git a/doc/api/sqlite.md b/doc/api/sqlite.md index 40ec877ddde..602a9780373 100644 --- a/doc/api/sqlite.md +++ b/doc/api/sqlite.md @@ -613,8 +613,10 @@ added: Loads a serialized database into this connection, replacing the current database. The deserialized database is writable. Existing prepared statements are finalized before deserialization is attempted, even if the operation -subsequently fails. This method is a wrapper around -[`sqlite3_deserialize()`][]. +subsequently fails. An \[`ERR_INVALID_STATE`]\[] error is thrown if the method is +called while a statement is executing, for example from a user-defined function, +an aggregate function, or an authorizer callback. This method is a wrapper +around [`sqlite3_deserialize()`][]. ```mjs import { DatabaseSync } from 'node:sqlite'; diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index 1272deb42f1..490ab90679a 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -1849,6 +1849,10 @@ void DatabaseSync::Deserialize(const FunctionCallbackInfo& args) { ASSIGN_OR_RETURN_UNWRAP(&db, args.This()); Environment* env = Environment::GetCurrent(args); THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open"); + THROW_AND_RETURN_ON_BAD_STATE( + env, + db->IsInCallback(), + "database cannot be deserialized while in a callback"); if (!args[0]->IsUint8Array()) { THROW_ERR_INVALID_ARG_TYPE(env->isolate(), diff --git a/test/parallel/test-sqlite-serialize.js b/test/parallel/test-sqlite-serialize.js index 77b9d9c5f48..e54cfa3c6a7 100644 --- a/test/parallel/test-sqlite-serialize.js +++ b/test/parallel/test-sqlite-serialize.js @@ -190,6 +190,23 @@ suite('DatabaseSync.prototype.deserialize()', () => { }); }); + test('throws if called while in a callback', (t) => { + const source = new DatabaseSync(':memory:'); + const serialized = source.serialize(); + source.close(); + + const db = new DatabaseSync(':memory:'); + t.after(() => db.close()); + db.function('deserialize_database', () => db.deserialize(serialized)); + const stmt = db.prepare('SELECT deserialize_database()'); + + t.assert.throws(() => stmt.get(), { + code: 'ERR_INVALID_STATE', + message: 'database cannot be deserialized while in a callback', + }); + t.assert.strictEqual(db.isOpen, true); + }); + test('throws if buffer argument is not a Uint8Array', (t) => { const db = new DatabaseSync(':memory:'); t.assert.throws(() => {