m4heshd / better-sqlite3-multiple-ciphers

better-sqlite3 with multiple-cipher encryption support 🔒
MIT License
137 stars 27 forks source link

Issue: 'The module was compiled against a different Node.js version' #55

Closed NoxFly closed 1 year ago

NoxFly commented 1 year ago

Hello,

Tech :

Step to reproduce :

npm i --save-dev better-sqlite3-multiple-ciphers
npm run dev # after adding some lines in a js file (see below)

JS file :

const Database = require('better-sqlite3-multiple-ciphers');

const db = new Database('data.db');

db.pragma('journal_mode = WAL');
db.pragma('key = "secret-key"');

const stmp = db.prepare('CREATE TABLE test (field TEXT)');
stmp.run();

db.close();

Given result :

(node:89407) UnhandledPromiseRejectionWarning: Error: The module '/home/noxfly/codes/nodejs/electron/myproject/node_modules/better-sqlite3-multiple-ciphers/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 108. This version of Node.js requires
NODE_MODULE_VERSION 116. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:1822)
    at Object.<anonymous> (node:internal/modules/cjs/loader:1356:18)
    at Object.func [as .node] (node:electron/js2c/asar_bundle:2:1822)
    at Module.load (node:internal/modules/cjs/loader:1126:32)
    at node:internal/modules/cjs/loader:967:12
    at Function._load (node:electron/js2c/asar_bundle:2:13330)
    at Module.require (node:internal/modules/cjs/loader:1150:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at bindings (/home/noxflycodes/nodejs/electron/myproject/node_modules/bindings/bindings.js:112:48)
    at new Database (/home/noxfly/codes/nodejs/electron/myproject/node_modules/better-sqlite3-multiple-ciphers/lib/database.js:48:64)

I've read the API doc, the Troobleshoot doc. I've tried all what is written in the troobleshoot documentation, nothing worked.

I also tried to rm -rf node_modules/ package-lock.json, clear npm cache and npm i again. Nothing worked.

m4heshd commented 1 year ago

Hi,

When you install a native module, it compiles or downloads the prebuilt binary against the Node version you have installed, which will always be different from the Electron version you're using because Node and Electron use different ABI versions from each other. You have to rebuild your native modules against your Electron version to be able to use them with Electron's embedded Node.

You have multiple ways you could rebuild your native modules for Electron but I'll just point you to the official method which is electron-rebuild.

Closing this issue since it's expected behavior.

NoxFly commented 1 year ago

As my first post tells it, I've already tried that (because it's on your troobleshoot doc), but this didn't worked. It's why I'm opening an issue. You can easily reproduce this issue, then tell me exactly what needs to be done. Because rebuild with npm rebuild or with electron-rebuild didn't worked.

m4heshd commented 1 year ago

Ok, that's because you have better-sqlite3-multiple-ciphers installed as a dev dependency. electron-rebuild doesn't rebuild dev dependencies by default. I don't recommend installing this library as a dev dependency unless you're actually only using it for development.

But still, you can try running electron-rebuild -f -w --types dev better-sqlite3-multiple-ciphers. It should work.

NoxFly commented 1 year ago

Thanks, this worked indeed.

For the following code :

const Database = require('better-sqlite3-multiple-ciphers');

const db = new Database('data.db');

db.pragma('journal_mode = WAL');

db.pragma('key = "secret-key"');

const stmp = db.prepare('CREATE TABLE mytable (myfield TEXT)');
stmp.run();

db.close();

The 2 first lines work (require & create database), but any single line after result in a crash.

/home/noxfly/codes/nodejs/electron/myproject/node_modules/electron/dist/electron exited with signal SIGSEGV

Do you have an idea ?

m4heshd commented 1 year ago

That's because your code itself is erroneous. You are setting the WAL journal mode before applying encryption, which could potentially corrupt the database. Encryption and decryption take precedence over everything else. Additionally, it's always a good practice not to change the journal mode repeatedly if it's already set to WAL.

Furthermore, after setting the journal mode and performing the initial encryption of a new database, it's advisable to do VACUUM, drop the connection, and then establish a new connection. Your code, in my opinion, should differ between a new database and an existing one.

Working with encrypted databases initially involves a lot of trial and error. I suggest reading more about SQLite3MultipleCiphers and engaging in thorough practice/testing until you become comfortable with it. Challenges increase significantly when dealing with tasks like asynchronous data manipulation and multi-threaded access, which you'll definitely need when working with Electron. Don't test your code on an Electron instance. Try things on a Node instance instead for the sake of clarity in code that could possibly generate errors.

For additional assistance in debugging such issues, you can seek help on Reddit and StackOverflow. In the meantime, if you encounter unexpected behavior, kindly create a new issue with an attached reproducible repository. This will allow me to clone the repository and debug with minimal time and effort, as time is currently a scarce luxury for me.

NoxFly commented 1 year ago

Thanks a lot for your time and your explanations, it is really clear.

NoxFly commented 11 months ago

Update, the crash of electron with signal SIGSEV continues. It seems, searching on the net, that there is a lot of similar conflicts when people use electron and another library (like my case with yours). For what I've seen, the reason is different for each library (for example, the 1st I found was about multiple threads used by the 2nd library, causing electron to crash).

I tried to reproduce the exact same code for creating the database and use it, without electron, and all things worked. Even a minimal code does the trick, just database creation causes a crash.

Here is the new issue : #59