4

I'm working on a 1-10k line personal Haskell project, and I'm using various IO-libraries such as Network.HTTP.Conduit inside workers spawned with Pipes.Concurrent.

I just realized that some of these IO libraries are throwing exceptions in edge cases.

Is there any way for GHC to give me compile-time warnings about uncaught exceptions? What is the best way to find out the exceptions a library can throw?

Thanks!

Craig
  • 255
  • 1
  • 6
  • You can make basically any function throw an exception when it evaluates one of the inputs which makes the whole task hazier. The inability to get a perfect tool doesn't mean a useful tool couldn't be created that could warn about many exceptions, but I don't know of any such tool. Liquid Haskell's totality checker does this in part but bundled with so much else that I'm not sure you can leverage it efficiently. – Thomas M. DuBuisson Mar 18 '18 at 02:04
  • Thanks for the ideas -- if no one else is doing it, I might do it myself. Do you know of any reason why this isn't in the type system like it is in Java? – Craig Mar 18 '18 at 02:57
  • It is just like Java - If you have a value of type `ExceptT e IO a`, then the `e` corresponds to the Java checked exceptions, and any other exceptions correspond to the Java unchecked exceptions. – Chris Martin Mar 18 '18 at 03:04
  • Not quite. https://hackage.haskell.org/package/http-conduit-2.3.0/docs/Network-HTTP-Conduit.html simpleHttp can throw exceptions, but it's not documented anywhere on the type – Craig Mar 18 '18 at 04:10
  • 1
    And in Java, anything can throw a `RuntimeException`, and that's not documented in the types. It comes down to community standards. My recommendation on finding libraries that violate the community standards (which in Haskell would be "don't throw when you can simply pass back structured data") would be to avoid using them. – Fried Brice Mar 18 '18 at 07:36
  • 2
    @FriedBrice I've argued that before with library authors without success. It turns out people prize easy of development over pure APIs. Using exceptions instead of sum types is the norm for major libraries such as cryptonite as well as low level libraries like network. – Thomas M. DuBuisson Mar 18 '18 at 16:24
  • 1
    @ThomasMDuBuisson This is truely a sad state of affairs. Whose "ease of development" does it support? Certainly not the library consumers. – Fried Brice Mar 18 '18 at 16:46
  • The author is talking about functions in `IO`. It's not accurate to say that APIs with `... -> IO (Either SomeErrorType a)` align to an accepted "community standard". Some people prefer that, while some consider it an anti-pattern. Personally I think both can be useful. – jberryman Mar 18 '18 at 23:39

1 Answers1

0

Just answering my own question as it stands in 2018. Hopefully this will improve over time.

At compile-time, there is no way to know which parts of your Haskell program can throw exceptions. Some libraries choose to return Either/Maybe monads to deal with edge cases safely and others choose to throw exceptions.

Personally, I believe this makes Haskell a lot less attractive to run in production, especially since these exceptions will rarely have stack traces.

Craig
  • 255
  • 1
  • 6