die with verbosity
- Dominant language
- Haskell
- Stars
- 1.7k
- Forks
- 750
- Avg merge
- 4d 3h
- Merged PRs (30d)
- 28
Description
Currently, the `die` function in Cabal does not take a `Verbosity` parameter. I propose to introduce a new version of the function, `die'`, which does, bringing it in line with `info`, `debug` and `warn`, all of which take `Verbosity`.
**Motivation.** The story is a bit long, so buckle up.
1. I was working on improving the error messages for Backpack related functionality (e.g., what we report when a reexport is ambiguous, or unification fails), and I noticed that the current cabal-testsuite approach of hardcoding a few strings to grep for in the output was not scaling. An approach which I know does work well when it comes to user output is "expect" style frameworks, like GHC's test suite, where the output of the programs is piped to a file and then compared against a gold standard. So, I decided to **add expect-style testing to cabal-testsuite.**
2. Now, there is one big problem with expect style testing, which is that when we run the Cabal, we normally run with `-v` for verbose output. I like this because it makes figuring out the error easier, often you can look at the logs and figure out what's going on. It's especially handy in CI, where it is essentially impossible to rerun the program with more debugging flags in any short amount of time. But the problem with verbose mode is that... well, it's really verbose, with a lot of output that is not stable across runs, let alone versions of GHC. So, my idea was to let Cabal **mark what output was non-verbose**, and use only that information the expect test.
3. Now, how would we do this? For info/warn, there is no problem: add a new flag to `Verbosity`, and use that to toggle the markers. But there is a problem: die doesn't take verbosity, so there's no way to attach markers to the output we get on failure! (Nor does `topHandler`, for that matter.) So we come to this ticket.
**Approaches.** So, how are we to solve this problem? I see a few possibilities:
1. Convert die to take verbosity, have it immediately print the message (according to the verbosity) and then throw an "empty" IOError which will get swallowed by top handler. Downside of this is that the error message unconditionally gets printed, even if a client catches the exception and recovers. This happens already, e.g., in new-build when it queries for pkg-config
2. Convert die to take verbosity, throw a new CabalError with the verbosity attached, let topHandler deicde what to do. Downside of this is that any code which is catching only IOErrors will fail to catch this exception. For example, in new-build's logic to catch pkg-config failure, it only matches IOError (this bug was driving me crazy)
3. Like (2), but throw an IOError. We have to attach the verbosity to IOError some how: the only way seems to be to tack it on to the error string, and then parse it again at topHandler site. Downside is you're using a stringly typed API, and it's kind of hacky.
4. Any code that dies, but client wants to catch, refactor it so it does't throw an exception. I don't know how many pieces of code would need to change but I don't see that many.
5. Treat the stderr specially in the test suite: always record it (whereas only marked stdout gets recorded)
A non-solution is to have topHandler take Verbosity. When we install topHandler we haven't parsed flags, so we don't know the verbosity
What do people like?
Contributor guide
Assessment
This issue has not been assessed yet.