Search code examples
shake-build-system

How can I get Shake to print errors only once?


If I ever have an error during a build, I see it twice

# ghc (for _build/lib/WCLoan.o)
# ghc (for _build/lib/WCLoan.o)
[2 of 2] Compiling WCLoan           ( src/WCLoan.hs, _build/lib/WCLoan.o )

src/WCLoan.hs:18:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
   |
18 | imAnError
   | ^^^^^^^^^
Error when running Shake build system:
* _build/lib/WCLoan.o
user error (Development.Shake.cmd, system command failed
Command: ghc -this-unit-id wcloan-0.0.1 src/WCLoan.hs -outputdir_build/lib -isrc:app:test -dynamic-too -O2 -j12 -fPIC -Werror -Wall -package-name wcloan-0.0.1 '-package base
-4.12.0.0' '-package calc-0.0.1' '-package vector-0.12.0.3'
Exit code: 1
Stderr:
src/WCLoan.hs:18:1: error:
    Parse error: module header, import declaration
    or top-level declaration expected.
   |
18 | imAnError
   | ^^^^^^^^^
)

I see that the error occurs during build, then is also shown under the line

Error when running Shake build system:

Is there anything I can do to have it show only once?


Solution

  • The error messages are coming from two distinct locations:

    • The first one is being printed by a command that Shake runs and writes to stderr with an error message. When you do cmd ... Shake defaults to EchoStderr True (print out the stderr stream to the console), but you can pass EchoStderr False to not echo the stderr.
    • The second is an exception being bubbled up by Haskell, as a ShakeException, which then gets printed out at the end, and includes the stderr. When you do cmd ... Shake defaults to WithStderr True to include the stderr in the exception, and you can pass WithStderr False to not include the stderr in the exception.

    However, because of the way Shake works, you may find that the error message comes out quite a long way before the end of the full Shake command. Therefore, I recommend leaving WithStderr as it is, if you do want to see stderr only once.