Skip to content

Commit 19da4cb

Browse files
divybotlittledivy
andauthored
fix(runtime): suggest --allow-scripts for bindings native addon error (#34666)
## Problem Importing an npm package that relies on a native addon (e.g. `npm:libxmljs`, pulled in by `npm:xsd-validator`) fails with: ``` error: Uncaught (in promise) Error: Could not locate the bindings file. Tried: → .../node_modules/libxmljs/build/xmljs.node → .../node_modules/libxmljs/build/Release/xmljs.node ... at bindings (.../node_modules/bindings/bindings.js:96:9) ``` The compiled `.node` file is missing because the npm lifecycle (build) scripts were not run. Deno already detects this situation and prints an actionable hint ("…run `deno install --allow-scripts` to setup `node_modules`"), but only for the Node-style `Cannot find module '…/build/Release/xxx.node'` / `Require stack:` error. The extremely common [`bindings`](https://www.npmjs.com/package/bindings) npm package (used by libxmljs and many other native addons) throws a *different* message — `Could not locate the bindings file. Tried: …` — so the helpful suggestion was never shown, leaving users stuck. ## Fix Extend the native-addon error detection in `get_suggestions_for_terminal_errors` to also match the `bindings` package error message, so the same `--allow-scripts` / `nodeModulesDir` hint is surfaced. ## Test Added a spec test (`tests/specs/run/node_addon_bindings_suggestion`) that reproduces the `bindings` error message and asserts the suggestion is emitted. Closes #27933 Closes denoland/divybot#396 Co-authored-by: divybot <divybot@users.noreply.github.com> Co-authored-by: Divy Srivastava <me@littledivy.com>
1 parent 75c1ba0 commit 19da4cb

4 files changed

Lines changed: 38 additions & 2 deletions

File tree

runtime/fmt_errors.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,18 @@ fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion<'_>> {
463463
// - /.../deno/npm/registry.npmjs.org/canvas/2.11.2/lib/bindings.js
464464
// - /.../.cache/deno/npm/registry.npmjs.org/canvas/2.11.2/lib/canvas.js
465465
// ```
466-
} else if msg.contains("Cannot find module")
466+
// as well as errors thrown by the `bindings` npm package (used by
467+
// libxmljs and many other native addons), like:
468+
// ```
469+
// Uncaught Error: Could not locate the bindings file. Tried:
470+
// → /.../node_modules/libxmljs/build/xmljs.node
471+
// → /.../node_modules/libxmljs/build/Release/xmljs.node
472+
// ```
473+
} else if (msg.contains("Cannot find module")
467474
&& msg.contains("Require stack")
468-
&& msg.contains(".node'")
475+
&& msg.contains(".node'"))
476+
|| (msg.contains("Could not locate the bindings file")
477+
&& msg.contains(".node"))
469478
{
470479
return vec![
471480
FixSuggestion::info_multiline(&[
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"args": "run main.js",
3+
"output": "main.out",
4+
"exitCode": 1
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Reproduces the error thrown by the `bindings` npm package (used by libxmljs
2+
// and many other native addons) when the compiled `.node` file is missing
3+
// because npm lifecycle scripts were not run. See denoland/deno#27933.
4+
const tried = [
5+
"/node_modules/libxmljs/build/xmljs.node",
6+
"/node_modules/libxmljs/build/Debug/xmljs.node",
7+
"/node_modules/libxmljs/build/Release/xmljs.node",
8+
];
9+
throw new Error(
10+
"Could not locate the bindings file. Tried:\n" +
11+
tried.map((p) => " → " + p).join("\n"),
12+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: Uncaught (in promise) Error: Could not locate the bindings file. Tried:
2+
[WILDCARD]xmljs.node
3+
throw new Error(
4+
^
5+
at file:///[WILDCARD]/main.js:9:7
6+
7+
info: Trying to execute an npm package using Node-API addons,
8+
these packages require local `node_modules` directory to be present.
9+
hint: Add `"nodeModulesDir": "auto" option to `deno.json`, and then run
10+
`deno install --allow-scripts=npm:<package> --entrypoint <script>` to setup `node_modules` directory.

0 commit comments

Comments
 (0)