Should we emit a dummy Output when a command fails to execute?
Opened this issue · 2 comments
Currently it's impossible to do something like this because one of the Exec
s will always fail:
let [<Literal>] IsUnix = String.EQ<Env.OS.Value, "Unix">.Value
// Dumb example of a command that needs to be different on Windows or Unix.
let [<Literal>] FileListing =
String.IF<IsUnix,
const Exec<"ls", "-la">.Output,
const Exec<"cmd", "/c dir">.Output>.Value
Emitting a dummy Output
property when the command fails to execute would make the above possible. But it may make the cause of an error harder to find in other unintended cases.
Some options I'm considering:
- Always emit
Output
, with a null or empty value if the command failed to run. - Add a new parameter eg
NullOnFailure = true
that decides whether to emit a nullOutput
if the command failed to run (false by default). - Always emit
Output
, and when the command fails to run, its value is the exception message.
I'm leaning towards option 2: it makes the above example more verbose, but the basic use case remains as safe as today.
Also leaning towards option 2, as you could actually differentiate between failing to run the command or timeout and a non-zero exit code. Just checking, would it do the same for Error
?
Another option could be to add a TryExec
and return a result (FSharp.Core.Result
). You'd have to match on it at runtime to get the value, but it's more explicit and would also allow you to actually use the exception message if you wanted to for whatever reason.
Just checking, would it do the same for
Error
?
Presumably yeah.
Another option could be to add a TryExec and return a result (FSharp.Core.Result). You'd have to match on it at runtime to get the value, but it's more explicit and would also allow you to actually use the exception message if you wanted to for whatever reason.
That could be useful, although it wouldn't be a "Literal" Provider anymore so it limits the use cases (can't pass it to another TP or an attribute).