summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2024-10-01 22:49:32 +0100
committerGitHub <noreply@github.com>2024-10-01 21:49:32 +0000
commitf9300004152ba4b3d091beb04d74f37b3b8ec281 (patch)
tree78ab2c9c6241a95ac7dbfce1902d258ef4623df0
parent41a70898adfc61b9020dfdfec17d374aac70d935 (diff)
feat: Add suggestion for packages using Node-API addons (#25975)
This commit adds a suggestion with information and hint how to resolve situation when user tries to run an npm package with Node-API addons using global cache (which is currently not supported). Closes https://github.com/denoland/deno/issues/25974
-rw-r--r--cli/main.rs25
-rw-r--r--runtime/fmt_errors.rs42
2 files changed, 63 insertions, 4 deletions
diff --git a/cli/main.rs b/cli/main.rs
index c0eccab5d..31bebc882 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -392,6 +392,31 @@ fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion> {
"Run again with `--unstable-webgpu` flag to enable this API.",
),
];
+ // Try to capture errors like:
+ // ```
+ // Uncaught Error: Cannot find module '../build/Release/canvas.node'
+ // Require stack:
+ // - /.../deno/npm/registry.npmjs.org/canvas/2.11.2/lib/bindings.js
+ // - /.../.cache/deno/npm/registry.npmjs.org/canvas/2.11.2/lib/canvas.js
+ // ```
+ } else if msg.contains("Cannot find module")
+ && msg.contains("Require stack")
+ && msg.contains(".node'")
+ {
+ return vec![
+ FixSuggestion::info_multiline(
+ &[
+ "Trying to execute an npm package using Node-API addons,",
+ "these packages require local `node_modules` directory to be present."
+ ]
+ ),
+ FixSuggestion::hint_multiline(
+ &[
+ "Add `\"nodeModulesDir\": \"auto\" option to `deno.json`, and then run",
+ "`deno install --allow-scripts=npm:<package> --entrypoint <script>` to setup `node_modules` directory."
+ ]
+ )
+ ];
}
}
diff --git a/runtime/fmt_errors.rs b/runtime/fmt_errors.rs
index b2cec2a5a..44a947732 100644
--- a/runtime/fmt_errors.rs
+++ b/runtime/fmt_errors.rs
@@ -27,23 +27,43 @@ enum FixSuggestionKind {
}
#[derive(Debug)]
+enum FixSuggestionMessage<'a> {
+ Single(&'a str),
+ Multiline(&'a [&'a str]),
+}
+
+#[derive(Debug)]
pub struct FixSuggestion<'a> {
kind: FixSuggestionKind,
- message: &'a str,
+ message: FixSuggestionMessage<'a>,
}
impl<'a> FixSuggestion<'a> {
pub fn info(message: &'a str) -> Self {
Self {
kind: FixSuggestionKind::Info,
- message,
+ message: FixSuggestionMessage::Single(message),
+ }
+ }
+
+ pub fn info_multiline(messages: &'a [&'a str]) -> Self {
+ Self {
+ kind: FixSuggestionKind::Info,
+ message: FixSuggestionMessage::Multiline(messages),
}
}
pub fn hint(message: &'a str) -> Self {
Self {
kind: FixSuggestionKind::Hint,
- message,
+ message: FixSuggestionMessage::Single(message),
+ }
+ }
+
+ pub fn hint_multiline(messages: &'a [&'a str]) -> Self {
+ Self {
+ kind: FixSuggestionKind::Hint,
+ message: FixSuggestionMessage::Multiline(messages),
}
}
}
@@ -238,7 +258,21 @@ fn format_js_error_inner(
FixSuggestionKind::Hint => write!(s, "{} ", cyan("hint:")).unwrap(),
FixSuggestionKind::Info => write!(s, "{} ", yellow("info:")).unwrap(),
};
- write!(s, "{}", suggestion.message).unwrap();
+ match suggestion.message {
+ FixSuggestionMessage::Single(msg) => {
+ write!(s, "{}", msg).unwrap();
+ }
+ FixSuggestionMessage::Multiline(messages) => {
+ for (idx, message) in messages.iter().enumerate() {
+ if idx != 0 {
+ writeln!(s).unwrap();
+ write!(s, " ").unwrap();
+ }
+ write!(s, "{}", message).unwrap();
+ }
+ }
+ }
+
if index != (suggestions.len() - 1) {
writeln!(s).unwrap();
}