Skip to content

Commit c428137

Browse files
committed
test(service-datasource): model better-sqlite3 13's own never-built error, not a phantom bindings
The never-built fixture required the bindings package relative to better-sqlite3 13, which does not depend on it; it resolved only through pnpm's hidden hoist of the copy better-sqlite3 12 brought in as better-auth 1.7.3's optional peer, and the 1.7.12 lift removed that copy. better-sqlite3 13 loads its addon with a plain require of build/Release/better_sqlite3.node, so the fixture now makes that require from the installed package against a module root that was never built, and the case asserts MODULE_NOT_FOUND. The two docblock sentences that named bindings' message now describe the 13.x error. No code moves. Claude-Session: https://claude.ai/code/session_011TdZ8GjixNZFLz1xJD9zzK Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9dcf97c commit c428137

2 files changed

Lines changed: 21 additions & 15 deletions

File tree

‎packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
* It is faked at the seam where `better-sqlite3` loads its addon: the knex
1919
* better-sqlite3 client's `acquireRawConnection` (`new Database(file)`).
2020
* The fake throws a REAL load error: Node's own `ERR_DLOPEN_FAILED`, or the
21-
* `bindings` package's own "not built" error.
21+
* `MODULE_NOT_FOUND` better-sqlite3's own loader meets when its addon was
22+
* never built.
2223
*/
2324

2425
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2526
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2627
import { createRequire } from 'node:module';
2728
import { tmpdir } from 'node:os';
28-
import { dirname, join } from 'node:path';
29+
import { join } from 'node:path';
2930
import { SqlDriver } from '@objectstack/driver-sql';
3031
import {
3132
NATIVE_SQLITE_WASM_FALLBACK_WARNING,
@@ -87,21 +88,24 @@ function realDlopenFailure(): Error {
8788
}
8889

8990
/**
90-
* The real error `better-sqlite3` throws when its addon was never built: the
91-
* `bindings` package it loads the addon through, asked for an addon that is
92-
* not there. It carries no code.
91+
* The real error `better-sqlite3` throws when its addon was never built. Its
92+
* 13.x loader (`lib/binding.js`) takes no helper package: with no prebuilt
93+
* binary for the platform it `require()`s `build/Release/better_sqlite3.node`
94+
* under its own module root, and Node answers `MODULE_NOT_FOUND`. Produced
95+
* here by that same require, made from the installed package, against a
96+
* module root that was never built.
9397
*/
9498
function realNotBuiltFailure(): Error {
9599
const fromHere = createRequire(import.meta.url);
96100
const fromDriver = createRequire(fromHere.resolve('@objectstack/driver-sql'));
97101
const betterSqlite3 = fromDriver.resolve('better-sqlite3/package.json');
98-
const bindings = createRequire(betterSqlite3)('bindings');
102+
const neverBuilt = join(dir, 'never-built', 'build', 'Release', 'better_sqlite3.node');
99103
try {
100-
bindings({ bindings: 'os_24950_never_built.node', module_root: dirname(betterSqlite3) });
104+
createRequire(betterSqlite3)(neverBuilt);
101105
} catch (error) {
102106
return error as Error;
103107
}
104-
throw new Error('bindings located an addon that was never built');
108+
throw new Error('required an addon that was never built');
105109
}
106110

107111
/**
@@ -170,9 +174,9 @@ describe('resolveSqliteDriver in development: a native addon that cannot load st
170174
expect(await resolved.driver.execute('SELECT 1 AS one')).toEqual([{ one: 1 }]);
171175
});
172176

173-
it('an addon that was never built (no code) steps down to wasm SQLite', async () => {
177+
it('an addon that was never built (MODULE_NOT_FOUND) steps down to wasm SQLite', async () => {
174178
const loadError = realNotBuiltFailure();
175-
expect((loadError as any).code).toBeUndefined();
179+
expect((loadError as any).code).toBe('MODULE_NOT_FOUND');
176180
await failNativeAddonLoad(loadError);
177181

178182
const resolved = await resolveDev(join(dir, 'dev.db'));

‎packages/services/service-datasource/src/sqlite-driver-fallback.ts‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@
3939
*
4040
* - **The addon cannot load — steps down.** An ABI mismatch (Node's
4141
* `ERR_DLOPEN_FAILED`, a `NODE_MODULE_VERSION` message), an addon that was
42-
* never built (`bindings`' "Could not locate the bindings file", which has
43-
* no code), or a missing `better-sqlite3` package. Today's path,
44-
* unchanged.
42+
* never built (better-sqlite3 13's loader `require()`s the absent
43+
* `build/Release/better_sqlite3.node`, and Node answers
44+
* `MODULE_NOT_FOUND`), or a missing `better-sqlite3` package. Today's
45+
* path, unchanged.
4546
* - **The database FILE cannot be opened or created, or is not a database —
4647
* re-thrown, as in production.** A path under a regular file, a parent
4748
* directory the driver cannot make, a permission refusal, a directory where
@@ -164,8 +165,9 @@ function isEphemeralFilename(filename: string): boolean {
164165
* An addon that cannot load never carries any of these. It surfaces at the
165166
* probe's `SELECT 1`, whose failure `SqlDriver.execute()` hands back as
166167
* `DATABASE_ERROR`, with the load error as its `cause`: Node's
167-
* `ERR_DLOPEN_FAILED`, `MODULE_NOT_FOUND`, or no code at all (`bindings`'
168-
* "Could not locate the bindings file"). A missing `better-sqlite3` package
168+
* `ERR_DLOPEN_FAILED`, or `MODULE_NOT_FOUND` (an addon that was never built:
169+
* better-sqlite3 13's loader `require()`s the absent
170+
* `build/Release/better_sqlite3.node`). A missing `better-sqlite3` package
169171
* fails at construction with knex's install hint, which has no code. None of
170172
* these matches.
171173
*

0 commit comments

Comments
 (0)