feat(node): suggest setting node.flavor if the flavor is not found in mirror#8206
feat(node): suggest setting node.flavor if the flavor is not found in mirror#8206
Conversation
Summary of ChangesHello @risu729, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly improves the user experience when installing Node.js by providing more informative error messages. Instead of a generic 404, users will now receive actionable advice on how to resolve issues related to missing Node.js versions or specific flavors when using custom mirrors, guiding them towards correct configuration. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds a helpful feature to suggest available Node.js flavors when a specific version is not found on a custom mirror. The implementation correctly intercepts 404 errors and queries the mirror's index.json to provide suggestions. However, there is a compilation error in the new suggest_available_flavors function that needs to be addressed.
| let versions: Vec<NodeVersion> = HTTP_FETCH | ||
| .json(base.join("index.json")?) | ||
| .await | ||
| .unwrap_or_default(); |
There was a problem hiding this comment.
This call to .unwrap_or_default() on a Result will not compile because Result does not implement this method. The likely intent is to default to an empty Vec<NodeVersion> if the HTTP request fails. You can achieve this by first converting the Result to an Option with .ok().
| .unwrap_or_default(); | |
| .ok().unwrap_or_default(); |
There was a problem hiding this comment.
Pull request overview
This PR adds a helpful suggestion feature to the Node.js plugin that guides users when a node version cannot be found in a custom mirror. When installing Node.js from a non-default mirror and encountering a 404 error, the tool now fetches the mirror's index.json to check if alternative "flavors" (like musl vs glibc) are available for the requested version and suggests setting the appropriate flavor.
Changes:
- Enhanced error handling in
install_compilingto detect 404 errors and suggest available flavors - Added
suggest_available_flavorsmethod to query mirror's index.json and provide helpful suggestions about available node flavors - Import of
DEFAULT_NODE_MIRROR_URLconstant to identify when custom mirrors are being used
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/plugins/core/node.rs
Outdated
| if let Some(reqwest_err) = err.root_cause().downcast_ref::<reqwest::Error>() | ||
| && reqwest_err.status() == Some(reqwest::StatusCode::NOT_FOUND) | ||
| && let Ok(Some(msg)) = self | ||
| .suggest_available_flavors(&opts.version, &Settings::get()) | ||
| .await | ||
| { | ||
| return Err(eyre::eyre!("{err}\n{msg}")); | ||
| } |
There was a problem hiding this comment.
The error handling pattern here differs from the established pattern in the codebase. In fetch_binary (line 69) and verify_with_gpg (line 292), the code uses http::error_code(&e) to check for 404 errors. This new code uses err.root_cause().downcast_ref::<reqwest::Error>() and checks the status directly. Consider using the existing http::error_code helper function for consistency with the rest of the codebase.
| if let Some(reqwest_err) = err.root_cause().downcast_ref::<reqwest::Error>() | |
| && reqwest_err.status() == Some(reqwest::StatusCode::NOT_FOUND) | |
| && let Ok(Some(msg)) = self | |
| .suggest_available_flavors(&opts.version, &Settings::get()) | |
| .await | |
| { | |
| return Err(eyre::eyre!("{err}\n{msg}")); | |
| } | |
| if crate::http::error_code(&err) == Some(404) { | |
| if let Ok(Some(msg)) = self | |
| .suggest_available_flavors(&opts.version, &Settings::get()) | |
| .await | |
| { | |
| return Err(eyre::eyre!("{err}\n{msg}")); |
| .await | ||
| .unwrap_or_default(); | ||
|
|
||
| if let Some(version) = versions.iter().find(|nv| { |
There was a problem hiding this comment.
The HTTP request error from fetching index.json is silently ignored with unwrap_or_default(). If the mirror is misconfigured or the network request fails for any reason (timeout, connection error, invalid JSON, etc.), this will silently return an empty vector and the function will return Ok(None), providing no helpful feedback to the user about why the suggestion system didn't work. Consider logging a warning or debug message when the fetch fails so users can troubleshoot mirror configuration issues.
| .await | |
| .unwrap_or_default(); | |
| if let Some(version) = versions.iter().find(|nv| { | |
| let versions: Vec<NodeVersion> = match HTTP_FETCH | |
| .json(base.join("index.json")?) | |
| .await | |
| { | |
| Ok(versions) => versions, | |
| Err(err) => { | |
| eprintln!( | |
| "Warning: failed to fetch Node mirror index.json from {}: {err}", | |
| base | |
| ); | |
| Vec::new() | |
| } | |
| }; |
| if let Some(version) = versions.iter().find(|nv| { | ||
| nv.version == format!("v{v}") || nv.version == v || nv.version == format!("v{v}.") | ||
| }) { | ||
| let os = os(); |
There was a problem hiding this comment.
The version comparison logic includes format!("v{v}.") which appears to be checking for a version string ending with a period. This seems incorrect as version strings typically don't end with a period. This condition would match versions like "v20.0.0." which is unlikely to be a valid version format. Consider removing this comparison or clarifying the intended behavior if there's a specific use case for versions ending with periods.
| let os = os(); | |
| nv.version == format!("v{v}") || nv.version == v |
| // If using default mirror, we don't need to suggest anything as it's likely a real 404 | ||
| if base.to_string() == DEFAULT_NODE_MIRROR_URL { | ||
| return Ok(None); | ||
| } |
There was a problem hiding this comment.
The URL comparison uses string comparison which may not be reliable for URLs. The URL base.to_string() could have variations like trailing slashes or different representations that would still be semantically equivalent. Consider using URL comparison directly or normalizing both URLs before comparison. For example, if one has a trailing slash and the other doesn't, they would be considered different even though they represent the same resource.
### 🚀 Features - **(mcp)** add run_task tool for executing mise tasks by @joaommartins in [#8179](#8179) - **(node)** suggest setting node.flavor if the flavor is not found in mirror by @risu729 in [#8206](#8206) ### 🐛 Bug Fixes - **(java)** sort order for shorthand versions by @roele in [#8197](#8197) - **(node)** migrate env vars to settings by @risu729 in [#8200](#8200) - **(registry)** apply overrides in shims by @risu729 in [#8199](#8199) - migrate MISE_CARGO_BINSTALL_ONLY to settings by @risu729 in [#8202](#8202) ### 📚 Documentation - **(doctor)** fix subcommand in an example by @risu729 in [#8198](#8198) ### 📦 Registry - add github backend for typst by @3w36zj6 in [#8210](#8210) ### Chore - **(test)** disable flaky Forgejo e2e test by @jdx in [#8211](#8211)
Resolves #5042