From f9a05068d6de247574fb764044a446d1d7ed2e9b Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:16:53 -0800 Subject: [PATCH] fix(install): handle invalid function error, and fallback to junctions regardless of the error (#26730) Fixes #26116. Handle the new error and treat is as lacking permission to make symlinks, but also to make this more robust, just always fall back to junctions no matter what the actual error is. Instead, warn if the error isn't one we've handled, but go on to attempt creating the junction --- cli/npm/managed/resolvers/local.rs | 16 +++++++++++----- cli/util/fs.rs | 4 +++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index 0968be8a7e..eddb0dc9b6 100644 --- a/cli/npm/managed/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -1035,12 +1035,18 @@ fn junction_or_symlink_dir( if symlink_err.kind() == std::io::ErrorKind::PermissionDenied => { USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed); - junction::create(old_path, new_path).map_err(Into::into) + junction::create(old_path, new_path) + .context("Failed creating junction in node_modules folder") + } + Err(symlink_err) => { + log::warn!( + "{} Unexpected error symlinking node_modules: {symlink_err}", + colors::yellow("Warning") + ); + USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed); + junction::create(old_path, new_path) + .context("Failed creating junction in node_modules folder") } - Err(symlink_err) => Err( - AnyError::from(symlink_err) - .context("Failed creating symlink in node_modules folder"), - ), } } diff --git a/cli/util/fs.rs b/cli/util/fs.rs index 2c34f486ad..d36c02242c 100644 --- a/cli/util/fs.rs +++ b/cli/util/fs.rs @@ -565,7 +565,9 @@ pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> { use std::os::windows::fs::symlink_dir; symlink_dir(oldpath, newpath).map_err(|err| { if let Some(code) = err.raw_os_error() { - if code as u32 == winapi::shared::winerror::ERROR_PRIVILEGE_NOT_HELD { + if code as u32 == winapi::shared::winerror::ERROR_PRIVILEGE_NOT_HELD + || code as u32 == winapi::shared::winerror::ERROR_INVALID_FUNCTION + { return err_mapper(err, Some(ErrorKind::PermissionDenied)); } }