Strange issue when upgrading Deno
See this example checking deno version each 5th second
import { Cron } from "jsr:@hexagon/croner";
import { $ } from "jsr:@david/dax";
// Check deno version every fifth second
new Cron("*/5 * * * * *", async () => {
try {
const result = await $`deno --version`.text();
console.log("Success!");
console.log(result); // 1
} catch (e) {
console.error("Failure!");
console.log(e);
}
});
After changing deno version while the script is running, e.g. deno upgrade --version 1.41.2 or similar
➜ test2 deno run -A dax_test.ts
Success!
deno 1.41.3 (release, x86_64-unknown-linux-gnu)
v8 12.3.219.9
typescript 5.3.3
Success!
deno 1.41.3 (release, x86_64-unknown-linux-gnu)
v8 12.3.219.9
typescript 5.3.3
Failure!
NotFound: Failed to spawn '/home/user/.deno/bin/deno (deleted)': No such file or directory (os error 2)
at spawnChildInner (ext:runtime/40_process.js:185:17)
at spawnChild (ext:runtime/40_process.js:206:10)
at Command.spawn (ext:runtime/40_process.js:474:12)
at spawnCommand (https://jsr.io/@david/dax/0.39.2/src/runtimes/process.deno.ts:4:49)
at executeCommandArgs (https://jsr.io/@david/dax/0.39.2/src/shell.ts:930:9)
at eventLoopTick (ext:core/01_core.js:208:9)
at async executeSimpleCommand (https://jsr.io/@david/dax/0.39.2/src/shell.ts:896:10)
at async executeSequentialList (https://jsr.io/@david/dax/0.39.2/src/shell.ts:512:20)
at async spawn (https://jsr.io/@david/dax/0.39.2/src/shell.ts:501:18)
at async CommandChild.pipedStdoutBuffer (https://jsr.io/@david/dax/0.39.2/src/command.ts:730:18) {
name: "NotFound",
code: "ENOENT"
}
Failure!
And it does not recover unless restarting the main process
Does this also happen if you write this same script in e.g. bash?
No, the problem seems to be related to Deno.execPath()
This works (using Deno.Command behind the scenes, and ["deno", "--version"] as command):
import { Cron } from "jsr:@hexagon/croner";
import { spawn } from "jsr:@cross/utils";
// Check deno version every fifth second
new Cron("*/10 * * * * *", async () => {
try {
const result = await spawn(["deno","--version"]);
console.log("Success!");
console.log(result);
} catch (e) {
console.error("Failure!");
console.log(e);
}
});
... but this gives the said error (using [Deno.execPath(), "--version"] as command);
import { Cron } from "jsr:@hexagon/croner";
import { spawn } from "jsr:@cross/utils";
// Check deno version every fifth second
new Cron("*/10 * * * * *", async () => {
try {
const result = await spawn([Deno.execPath(),"--version"]);
console.log("Success!");
console.log(result);
} catch (e) {
console.error("Failure!");
console.log(e);
}
});
Could it be that dax uses Deno.execPath() internally, and Deno.execPath() somehow get changed to /home/user/.deno/bin/deno (deleted) when deno is upgraded?
Edit: Yep, just removing (deleted) from Deno.execPath() resolves the problem in my example. This works [Deno.execPath().replace(" (deleted)",""),"--version"].
Hmm, maybe deno → Deno.execPath() was added as a fix for people who didn't have deno in their PATH.
This is surprising behavior, though, if you're expecting it to find deno in your path. And would be a real head-scratcher if you've got multiple versions of Deno installed and Dax picks one that's not the one in your path.
Maybe the fix is as simple as trying the path first, then falling back to execPath if it wasn't found?