I spent some time reading through issue #309 and the associated discussions in yesodweb/wai#496 and PR #954 about how servant-server appears to incorrectly handle exceptions with respect to how wai/warp expects to operate.
The unfortunate side effect of this behavior is that any uncaught exceptions within a Servant application will not be registered by any wai middleware as a 500 exception, which can seriously negatively impact user experience around automated logging, metrics tracking, etc.
As far as I can tell, the solution proposed in #309 around deeply evaluating Responses in toApplication before creating a ResponseReceived (to provide to wai) won't work for ensuring that any impure exceptions in thunks are caught (Response cannot have a valid NFData instance to the best of my knowledg).
The machinery for forcing evaluation, catching exceptions, and generating correct waiResponses would have to live somewhere else in Servant, probably using a similar combination of techniques as to what Yesod uses:
In my mind, catching impure exceptions cannot happen in servant without potentially serious performance degradation. Also, it is against the idea that the types represent the behavior of the rest API as completely as possible.
I can see two things working:
Don't allow partial handlers and impure exceptions.
1 is not always easy, especially if you're using libraries that are sometimes subtle about being patrial; but together with 2., I think it is the way to go. Impure exceptions should be 5xx errors and treated as software bugs.
I've now read through #309 and #954 a little, and changed my mind to "it's conceivable that we find a consensus for toApplication to force the Response under certain conditions, but I don't like it:: it complicates the library and encourages the use of impure exceptions.
This is exclusively about impure exceptions, or is that where I'm wrong?
to re-iterate: we're not talking about having the servant types represent exceptions, but about impure exceptions (ie. undefined or error "bla", ie. errors that are outside the control of the types by necessity). the issue is that due to lazyness, these impure exceptions can not only make past servant, but also past the middleware (where they are already outside the control of the types), and thus choke warp in a way that does not get logged or rendered into a properly shaped 5xx (with proper body content type and all).
the more i think about this, the more i'm certain the solution should be the warp hooks.