Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better error messages when file does not exist #184

Open
anka-213 opened this issue Jun 10, 2020 · 8 comments
Open

Better error messages when file does not exist #184

anka-213 opened this issue Jun 10, 2020 · 8 comments

Comments

@anka-213
Copy link

Currently, we get cryptic error messages like:

createProcess: runInteractiveProcess: exec: does not exist (No such file or directory)

Which tells us nothing about what it is that we were trying to run that does not exist. It would be very helpful for debugging if the path that does not exist was included in the error message.

@snoyberg
Copy link
Collaborator

I don't see a problem with such a change, would you be interested in submitting a PR?

@juhp
Copy link

juhp commented Oct 6, 2020

+:100: for this

This has bothered me for a long time actually...

$ cat > myprog.hs
import System.Process
main = rawSystem "a-tool" []
$ ghc myprog
$ ./myprog
myprog: a-tool: rawSystem: runInteractiveProcess: exec: does not exist (No such file or directory)

The error message should be something like:

myprog: rawSystem: a-tool: command not found

I tried a bit to track down where/how the error message is built, but didn't succeed yet: any pointers would be helpful.

@Fuuzetsu
Copy link
Member

Fuuzetsu commented Oct 6, 2020

I'm making an uneducated guess and going to say here:

execvp(args[0], args);

Edit: notably, childFailed function. As the message comes from the OS, I think probably you want to examine the error code somehow and do some special behaviour there that adds the process name?

@juhp
Copy link

juhp commented May 17, 2021

Thanks @Fuuzetsu for the helpful comment: it is also confusing that the C function is also called runInteractiveProcess.
Indeed the error substring "runInteractiveProcess: exec" comes from the runInteractiveProcess in runProcess.c
along with a list of other potential failure errors (pipe, chdir, setuid, initgroups, etc).

I am still trying to work out how to move the executable name to later in the error message.

@juhp
Copy link

juhp commented May 19, 2021

I am wondering if this is could even be a ghc bug: maybe something like throwIO# in ghc-prim possibly? since the process command filepath is put into the IOException:

So far I tracked down from System.Process: createProcess_ (process) -> createProcess_Internal.
Then perhaps withFilePathException fpath -> ioError (ioeSetFileName ex fpath) (base) -> ioException -> throwIO -> raiseIO# (ghc-prim).

I think I need a ghc build tree to look at the generated ghc-prim files, to check what it does, though the actual final error message might still be assembled higher up in the stack.

@Fuuzetsu
Copy link
Member

I don't really follow. I haven't read the code closely, but isn't it just the case of adding args[0] to this line?

*failed_doing = "runInteractiveProcess: exec";

@juhp
Copy link

juhp commented May 20, 2021

Probably and removing it from the start of the error string...

@anka-213
Copy link
Author

anka-213 commented Nov 3, 2021

I'm trying to figure out how the cmd name is added to the beginning. It might be this line?

withFilePathException cmd $

And then the rest is composed here

throwErrno (fun ++ ": " ++ failedDoing)

And finally, the actual error message is extracted from the C errno by the throwErrNo function and combined with the context from the failedDoing variable.

https://hackage.haskell.org/package/base-4.16.0.0/docs/src/Foreign.C.Error.html#throwErrno

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants