1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

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
This commit is contained in:
Bartek Iwańczuk 2024-10-01 22:49:32 +01:00 committed by GitHub
parent 41a70898ad
commit f930000415
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 4 deletions

View file

@ -392,6 +392,31 @@ fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion> {
"Run again with `--unstable-webgpu` flag to enable this API.", "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."
]
)
];
} }
} }

View file

@ -26,24 +26,44 @@ enum FixSuggestionKind {
Hint, Hint,
} }
#[derive(Debug)]
enum FixSuggestionMessage<'a> {
Single(&'a str),
Multiline(&'a [&'a str]),
}
#[derive(Debug)] #[derive(Debug)]
pub struct FixSuggestion<'a> { pub struct FixSuggestion<'a> {
kind: FixSuggestionKind, kind: FixSuggestionKind,
message: &'a str, message: FixSuggestionMessage<'a>,
} }
impl<'a> FixSuggestion<'a> { impl<'a> FixSuggestion<'a> {
pub fn info(message: &'a str) -> Self { pub fn info(message: &'a str) -> Self {
Self { Self {
kind: FixSuggestionKind::Info, 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 { pub fn hint(message: &'a str) -> Self {
Self { Self {
kind: FixSuggestionKind::Hint, 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::Hint => write!(s, "{} ", cyan("hint:")).unwrap(),
FixSuggestionKind::Info => write!(s, "{} ", yellow("info:")).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) { if index != (suggestions.len() - 1) {
writeln!(s).unwrap(); writeln!(s).unwrap();
} }