* Run error catching middleware before gzip
The `catchError` middleware was running over gzipped responses, and this
caused the wrapping logic to fail, and to display a gzip-encoded error
message.
* Avoid unnecessary conversion to Text
This prevents the response body to being preemptively converted to Text
when wrapping an error response inside a JSON object.
* Use IORef instead of TVar for extracting body
There is no need to use STM in `lazyResponseBody`, since it is not
interacting with any other STM action, and just using TVars inside
`atomically` blocks.