0

I'm trying to create some middleware that will send 500 errors to a remote server. The error information is in the response body.

How can I get the response body from a Response as any kind of string? I see responseToStream but I can't figure out how to use it.

import Network.Wai
import Data.ByteString.Lazy (ByteString)

responseBody :: Response -> IO ByteString
responseBody res = _
Sean Clark Hess
  • 15,859
  • 12
  • 52
  • 100
  • 1
    The result of `responseToStream` is a 3-tuple; I'm guessing by "body" you mean you are interested in the 3rd component and not the first two (which are concrete, i.e. non-abstract, algebraic types, so you can access their fields directly). For the 3rd comp, you could probably just pass a function for `Builder -> IO ()` which `mappend`s each `Builder` to an `IORef` (or `MVar` in a concurrent setting) - "the first parameter provides a means of sending another chunk of data" (here 'sending' is just saving in memory). – user2407038 Aug 03 '17 at 00:29

1 Answers1

1

An implementation of the comment by @user2407038:

import Data.IORef (newIORef,modifyIORef',readIORef)
import Data.Monoid ((<>))
import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Builder (toLazyByteString)

import Network.Wai

responseBody :: Response -> IO ByteString
responseBody res =
  let (status,headers,body) = responseToStream res in
  body $ \f -> do
    content <- newIORef mempty
    f (\chunk -> modifyIORef' content (<> chunk)) (return ())
    toLazyByteString <$> readIORef content
ryachza
  • 4,460
  • 18
  • 28