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

Exception while running inproc #269

Open
viviag opened this issue Dec 8, 2017 · 12 comments
Open

Exception while running inproc #269

viviag opened this issue Dec 8, 2017 · 12 comments

Comments

@viviag
Copy link

viviag commented Dec 8, 2017

Resolver nightly-2017-12-08:

Program dies with no error message on the line view $ inproc "git" ["describe"] empty or sh $ inproc "git" ["describe"] empty etc.
When trying to use inprocWithErr I see Left ... but it even dies.

in GHCI:

>>> view $ inproc "git" ["describe"] empty
fatal: No names found, cannot describe anything.
*** Exception: ExitFailure 128
@Gabriella439
Copy link
Owner

That is intentional. inproc should throw an exception if the underlying process returns a non-zero exit code. See: #245

@viviag
Copy link
Author

viviag commented Dec 15, 2017

Maybe it's a good idea to optionally override this behavior?
git describe in example above returns non-zero exit code when there is no annotated tags in the project. It's normal. And then I want to call it deep in program and parse with Control.Foldl.head to get latest version. I want it to return anyway because I'm using it only as data source. I can catch and handle exception here but is such case exceptional?

@PierreR
Copy link
Contributor

PierreR commented Dec 15, 2017

@viviag Maybe inprocWithErr might fit your need ? (or procStrictWithErr if you need the exit code)

@viviag
Copy link
Author

viviag commented Dec 15, 2017

@PierreR Thank you! It works, I didn't check it properly last time I tried.

@viviag
Copy link
Author

viviag commented Dec 15, 2017

@PierreR No, I'm wrong only now, sorry for haste.
In GHCi:

Fold Turtle Data.Either.Combinators> fold (fromRight "" <$> Turtle.inprocWithErr "git" ["describe", "--tags", "origin/master"] empty) Fold.head
*** Exception: ExitFailure 128

@lingnand
Copy link
Collaborator

With the latest patch on MonadCatch instance for Shell, you can now easily handle exceptional cases like this.

gitOutput :: Shell (Maybe Line)
gitOutput = (Just <$> inproc "git" ["describe"] empty) `catch` \(e :: ExitCode) -> pure Nothing

I agree with the api throwing exception in this case as it depends on the interpretation of the user to decide whether a non-zero exit code is recoverable or not - in fact, the program being called is relying on this exit code mechanism to communicate additional info beyond text output. As long as it's sufficiently straightforward to write exception handling code, e.g. with the example here now one can differentiate between 'having annotated code' vs 'no annotated code' (or you can simple do empty in the err handling clause to remove the need of Maybe wrapper); I think we wouldn't have the need for optional override of throwing exception.

@Gabriella439
Copy link
Owner

Yeah, I recommend using the newly added support for MonadCatch to handle the exception thrown from inproc/inshell. I'm cutting a new release soon to publish this to Hackage: #272

@neongreen
Copy link

neongreen commented Oct 3, 2018

A warning (I got bitten by this): the gitOutput snippet above behaves quite counterintuitively. If you view it and the exit code is non-zero, it will print all lines and then Nothing; but if you foldShell it and the exit code is non-zero, you'll only get Nothing and no output lines, because the fold will be restarted by the exception.

All in all, I still don't know how to write a Shell that would let me get the stdout, stderr, and exit code, other than doing something hackish like writing lines during the foldShell into a TQueue or something so that the catch won't eat them. Any advice?

@Gabriella439
Copy link
Owner

Gabriella439 commented Oct 3, 2018

@neongreen: You can use a non-streaming solution to get stdout/stderr/exit-code by using Turtle.procStrictWithErr

@neongreen
Copy link

Sure, but I want a streaming solution.

@Gabriella439
Copy link
Owner

@neongreen: Yeah, in that case you'll probably have to store results in a buffer. The API doesn't provide a way to resume where a stream left off in the event of an exception.

@deliciouslytyped
Copy link

deliciouslytyped commented Oct 23, 2019

I'm not sure what it means to continue after getting an exit code, but in the case where I just want an exit code and the data, but still using streams, without needing to...continue - how can I do that?

Edit: after some fiddling I got the git output example to work, though having to wrap it in another layer of Either feels a bit clumsy - I'm not an expert however.

view $ Control.Monad.Catch.catch
  ((Right <$> inshellWithErr "seq 1 10; false" empty) <|> (select [Left ExitSuccess]))
  (\(e :: ExitCode) -> pure $ Left e)

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

6 participants