diff --git a/lib/fs.js b/lib/fs.js index cde3a582727f80..5249af604e9eb9 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1793,23 +1793,27 @@ function symlink(target, path, type, callback) { // Continue regardless of error. } if (absoluteTarget !== undefined) { - stat(absoluteTarget, (err, stat) => { - const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file'; - const resolvedFlags = stringToSymlinkType(resolvedType); - const destination = preprocessSymlinkDestination(target, - resolvedType, - path); - - const req = new FSReqCallback(); - req.oncomplete = callback; - binding.symlink( - destination, - path, - resolvedFlags, - req, - ); - }); - return; + try { + stat(absoluteTarget, (err, stat) => { + const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file'; + const resolvedFlags = stringToSymlinkType(resolvedType); + const destination = preprocessSymlinkDestination(target, + resolvedType, + path); + + const req = new FSReqCallback(); + req.oncomplete = callback; + binding.symlink( + destination, + path, + resolvedFlags, + req, + ); + }); + return; + } catch (statErr) { + // If stat fails, fall back to default symlink creation + } } } diff --git a/test/parallel/test-fs-symlink-windows-error-handling.js b/test/parallel/test-fs-symlink-windows-error-handling.js new file mode 100644 index 00000000000000..91522e4d92984e --- /dev/null +++ b/test/parallel/test-fs-symlink-windows-error-handling.js @@ -0,0 +1,38 @@ +// Test for Windows symlink error handling when stat() fails +'use strict'; + +const common = require('../common'); + +// This test is specifically for Windows symlink behavior +if (!common.isWindows) { + common.skip('Windows-specific test'); +} + +if (!common.canCreateSymLink()) { + common.skip('insufficient privileges'); +} + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const tmpdir = require('../common/tmpdir'); + +tmpdir.refresh(); + +// Test that symlink creation doesn't crash when stat() fails on absoluteTarget +// This tests the try-catch error handling added around stat() call +const target = './nonexistent-target'; +const linkPath = tmpdir.resolve('test-symlink'); + +// Create a symlink with a relative target that would cause stat() to fail +// when resolving the absolute target path +fs.symlink(target, linkPath, common.mustSucceed(() => { + // Verify the symlink was created successfully despite stat() error + fs.lstat(linkPath, common.mustSucceed((stats) => { + assert(stats.isSymbolicLink()); + })); + + fs.readlink(linkPath, common.mustSucceed((destination) => { + assert.strictEqual(destination, target); + })); +})); \ No newline at end of file