Skip to content

Commit

Permalink
fix(fs): improve the error message when the symlink target does not e…
Browse files Browse the repository at this point in the history
…xist
  • Loading branch information
kt3k committed Nov 20, 2024
1 parent 82ccee6 commit 095173b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
24 changes: 22 additions & 2 deletions fs/ensure_symlink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,17 @@ export async function ensureSymlink(
linkName: string | URL,
) {
const targetRealPath = resolveSymlinkTarget(target, linkName);
const srcStatInfo = await Deno.lstat(targetRealPath);
let srcStatInfo;
try {
srcStatInfo = await Deno.lstat(targetRealPath);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
throw new Deno.errors.NotFound(
`Cannot ensure symlink as the target path does not exist: ${targetRealPath}`,
);
}
throw error;
}
const srcFilePathType = getFileInfoType(srcStatInfo);

await ensureDir(dirname(toPathString(linkName)));
Expand Down Expand Up @@ -112,7 +122,17 @@ export function ensureSymlinkSync(
linkName: string | URL,
) {
const targetRealPath = resolveSymlinkTarget(target, linkName);
const srcStatInfo = Deno.lstatSync(targetRealPath);
let srcStatInfo;
try {
srcStatInfo = Deno.lstatSync(targetRealPath);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
throw new Deno.errors.NotFound(
`Cannot ensure symlink as the target path does not exist: ${targetRealPath}`,
);
}
throw error;
}
const srcFilePathType = getFileInfoType(srcStatInfo);

ensureDirSync(dirname(toPathString(linkName)));
Expand Down
31 changes: 30 additions & 1 deletion fs/ensure_symlink_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// TODO(axetroy): Add test for Windows once symlink is implemented for Windows.
import { assert, assertEquals, assertRejects, assertThrows } from "@std/assert";
import {
assert,
assertEquals,
assertMatch,
assertRejects,
assertThrows,
} from "@std/assert";
import * as path from "@std/path";
import { ensureSymlink, ensureSymlinkSync } from "./ensure_symlink.ts";
import { IS_DENO_2 } from "../internal/_is_deno_2.ts";
Expand Down Expand Up @@ -239,6 +245,29 @@ Deno.test("ensureSymlinkSync() creates symlink with relative target", function (
Deno.removeSync(testDir, { recursive: true });
});

Deno.test("ensureSymlink() rejects when the target path doesn't exist", async () => {
const e = await assertRejects(
async () => {
await ensureSymlink("non-existent-target", "non-existent-link");
},
Deno.errors.NotFound,
);
assertMatch(
e.message,
/^Cannot ensure symlink as the target path does not exist: .*non-existent-target$/,
);
});

Deno.test("ensureSymlinkSync() throws when the target path doesn't exist", async () => {
const e = assertThrows(() => {
ensureSymlinkSync("non-existent-target", "non-existent-link");
}, Deno.errors.NotFound);
assertMatch(
e.message,
/^Cannot ensure symlink as the target path does not exist: .*non-existent-target$/,
);
});

Deno.test("ensureSymlink() works with URLs", {
// TODO(kt3k): The 2nd test case doesn't pass on Windows. Fix it.
ignore: Deno.build.os === "windows",
Expand Down

0 comments on commit 095173b

Please sign in to comment.