fix(bun): use native bun:sqlite during startup to avoid N-API crash (#11468)

Validated in a combined 4-PR batch worktree off release/v3.8.51 tip (Bun-native SQLite infrastructure cluster from the same contributor).
- Focused test: bunSqliteAdapter.test.ts — part of batch's 5/5 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff

Thanks for tracing this to the pre-boot better-sqlite3 require — a native NAPI abort that JS try/catch cannot recover from is exactly the kind of failure mode that needs the guard moved earlier, and aligning bootstrap/sync-env with the already-preferred bun:sqlite driver is the right fix.
This commit is contained in:
Nguyễn Viết Tuấn
2026-08-26 06:31:34 +07:00
committed by GitHub
parent 3f6a881b6c
commit 9ad90fe7a3
5 changed files with 77 additions and 1 deletions

View File

@@ -82,6 +82,32 @@ function hasEncryptedCredentials(dataDir) {
const dbPath = join(dataDir, "storage.sqlite");
if (!existsSync(dbPath)) return false;
if (process.versions.bun) {
try {
const { Database } = require("bun:sqlite");
const db = new Database(dbPath, { readonly: true, create: false });
try {
const row = db
.query(
`SELECT 1
FROM provider_connections
WHERE access_token LIKE 'enc:v1:%'
OR refresh_token LIKE 'enc:v1:%'
OR api_key LIKE 'enc:v1:%'
OR id_token LIKE 'enc:v1:%'
LIMIT 1`
)
.get();
return !!row;
} finally {
db.close();
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Unable to inspect existing database at ${dbPath}: ${message}`);
}
}
try {
const Database = require("better-sqlite3");
const db = new Database(dbPath, { readonly: true, fileMustExist: true });

View File

@@ -93,12 +93,38 @@ function hasEncryptedCredentials(dataDir) {
const dbPath = join(dataDir, "storage.sqlite");
if (!existsSync(dbPath)) return false;
const require = createRequire(import.meta.url);
if (process.versions.bun) {
try {
const { Database } = require("bun:sqlite");
const db = new Database(dbPath, { readonly: true, create: false });
try {
const row = db
.query(
`SELECT 1
FROM provider_connections
WHERE access_token LIKE 'enc:v1:%'
OR refresh_token LIKE 'enc:v1:%'
OR api_key LIKE 'enc:v1:%'
OR id_token LIKE 'enc:v1:%'
LIMIT 1`
)
.get();
return !!row;
} finally {
db.close();
}
} catch {
return false;
}
}
try {
// Resolve `require` lazily here (not at module top-level): when this file is
// bundled into a standalone route, a top-level `createRequire(import.meta.url)`
// throws during module evaluation and 500s the whole route (#5006). Inside this
// guarded block, any failure simply returns false (the safe default below).
const require = createRequire(import.meta.url);
const Database = require("better-sqlite3");
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
try {