diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Revision history for influxdb
 
+## v1.5.0 - 2018-03-15
+
+* Change UnexpectedResponse constructor to include the request and throw it in place of UserError in query/write/manage
+* Relax upper version bound for doctest
+* Extend Haddock comments in Database.InfluxDB.Line
+
+The first item is a breaking change.
+
 ## v1.4.0 - 2018-03-13
 
 * Implement proper escaping/quoting for queries ([#54](https://github.com/maoe/influxdb-haskell/pull/54))
diff --git a/influxdb.cabal b/influxdb.cabal
--- a/influxdb.cabal
+++ b/influxdb.cabal
@@ -1,5 +1,5 @@
 name: influxdb
-version: 1.4.0
+version: 1.5.0
 synopsis: Haskell client library for InfluxDB
 description:
   @influxdb@ is a Haskell client library for InfluxDB.
@@ -116,7 +116,7 @@
   main-is:             doctests.hs
   build-depends:
       base
-    , doctest >= 0.11.3 && < 0.15
+    , doctest >= 0.11.3 && < 0.16
     , QuickCheck >= 2.10 && < 2.12
     , influxdb
     , template-haskell
diff --git a/src/Database/InfluxDB/Line.hs b/src/Database/InfluxDB/Line.hs
--- a/src/Database/InfluxDB/Line.hs
+++ b/src/Database/InfluxDB/Line.hs
@@ -5,17 +5,22 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TemplateHaskell #-}
 module Database.InfluxDB.Line
-  ( Line(Line)
+  ( -- $setup
+
+  -- * Types and accessors
+    Line(Line)
   , measurement
   , tagSet
   , fieldSet
   , timestamp
 
+  -- * Serializers
   , buildLine
   , buildLines
   , encodeLine
   , encodeLines
 
+  -- * Other types
   , LineField
   , Field(..)
   , Precision(..)
@@ -35,6 +40,28 @@
 import Database.InfluxDB.Internal.Text
 import Database.InfluxDB.Types
 
+{- $setup
+The Line protocol implementation.
+
+>>> :set -XOverloadedStrings
+>>> import Database.InfluxDB
+>>> import Data.Time
+>>> import qualified Data.ByteString.Lazy.Char8 as BL8
+>>> import System.IO (stdout)
+>>> :{
+let l1 = Line "cpu_usage"
+      (Map.singleton "cpu" "cpu-total")
+      (Map.fromList
+        [ ("idle",   FieldFloat 10.1)
+        , ("system", FieldFloat 53.3)
+        , ("user",   FieldFloat 46.6)
+        ])
+      (Just $ parseTimeOrError False defaultTimeLocale
+        "%F %T%Q %Z"
+        "2017-06-17 15:41:40.42659044 UTC") :: Line UTCTime
+:}
+-}
+
 -- | Placeholder for the Line Protocol
 --
 -- See https://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/ for the
@@ -52,19 +79,39 @@
   -- ^ Timestamp (optional)
   }
 
+-- | Serialize a 'Line' to a lazy bytestring
+--
+-- >>> BL8.putStrLn $ encodeLine (scaleTo Second) l1
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
 encodeLine
   :: (time -> Int64)
+  -- ^ Function to convert time to an InfluxDB timestamp
+  --
+  -- Use 'scaleTo' for HTTP writes and 'roundTo' for UDP writes.
   -> Line time
   -> L.ByteString
 encodeLine toTimestamp = B.toLazyByteString . buildLine toTimestamp
 
+-- | Serialize 'Line's to a lazy bytestring
+--
+-- >>> BL8.putStr $ encodeLines (scaleTo Second) [l1, l1]
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
+--
 encodeLines
   :: Foldable f
   => (time -> Int64)
+  -- ^ Function to convert time to an InfluxDB timestamp
+  --
+  -- Use 'scaleTo' for HTTP writes and 'roundTo' for UDP writes.
   -> f (Line time)
   -> L.ByteString
 encodeLines toTimestamp = B.toLazyByteString . buildLines toTimestamp
 
+-- | Serialize a 'Line' to a bytestring 'B.Buider'
+--
+-- >>> B.hPutBuilder stdout $ buildLine (scaleTo Second) l1
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
 buildLine
   :: (time -> Int64)
   -> Line time
@@ -104,6 +151,12 @@
   FieldString t -> "\"" <> TE.encodeUtf8Builder (escapeStringField t) <> "\""
   FieldBool b -> if b then "true" else "false"
 
+-- | Serialize 'Line's to a bytestring 'B.Builder'
+--
+-- >>> B.hPutBuilder stdout $ buildLines (scaleTo Second) [l1, l1]
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
+-- cpu_usage,cpu=cpu-total idle=10.1,system=53.3,user=46.6 1497714100
+--
 buildLines
   :: Foldable f
   => (time -> Int64)
diff --git a/src/Database/InfluxDB/Manage.hs b/src/Database/InfluxDB/Manage.hs
--- a/src/Database/InfluxDB/Manage.hs
+++ b/src/Database/InfluxDB/Manage.hs
@@ -73,7 +73,7 @@
   let body = HC.responseBody response
   case eitherDecode' body of
     Left message ->
-      throwIO $ UnexpectedResponse message body
+      throwIO $ UnexpectedResponse message request body
     Right val -> case A.parse (parseResults (params^.precision)) val of
       A.Success (_ :: V.Vector Void) -> return ()
       A.Error message -> do
@@ -82,7 +82,11 @@
           throwIO $ ServerError message
         when (HT.statusIsClientError status) $
           throwIO $ ClientError message request
-        fail $ "BUG: " ++ message ++ " in Database.InfluxDB.Manage.manage"
+        throwIO $ UnexpectedResponse
+          ("BUG: " ++ message ++ " in Database.InfluxDB.Manage.manage")
+          request
+          (encode val)
+
   where
     request = HC.setQueryString qs $ manageRequest params
     qs =
@@ -160,37 +164,37 @@
 
 -- | Query ID
 --
--- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
--- >> v ^.. each.qid
--- >[149250]
+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v ^.. each.qid
+-- ...
 qid :: Lens' ShowQuery Int
 
 -- | Query text
 --
--- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
--- >> v ^.. each.queryText
--- >["SHOW QUERIES"]
+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v ^.. each.queryText
+-- ...
 queryText :: Lens' ShowQuery Query
 
 -- |
--- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
--- >> v ^.. each.database
--- >["_internal"]
+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v ^.. each.database
+-- ...
 instance HasDatabase ShowQuery where
   database = _database
 
 -- | Duration of the query
 --
--- >> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
--- >> v ^.. each.duration
--- >[0.06062s]
+-- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v ^.. each.duration
+-- ...
 duration :: Lens' ShowQuery NominalDiffTime
 
 makeLensesWith (lensRules & generateSignatures .~ False) ''ShowSeries
 
 -- | Series name
 --
--- >> v <- query (queryParams "_internal") "SHOW SERIES" :: IO (V.Vector ShowSeries)
--- >> length $ v ^.. each.key
--- >755
+-- >>> v <- query (queryParams "_internal") "SHOW SERIES" :: IO (V.Vector ShowSeries)
+-- >>> length $ v ^.. each.key
+-- ...
 key :: Lens' ShowSeries Key
diff --git a/src/Database/InfluxDB/Ping.hs b/src/Database/InfluxDB/Ping.hs
--- a/src/Database/InfluxDB/Ping.hs
+++ b/src/Database/InfluxDB/Ping.hs
@@ -129,6 +129,7 @@
       Nothing ->
         throwIO $ UnexpectedResponse
           "The X-Influxdb-Version header was missing in the response."
+          request
           ""
   `catch` (throwIO . HTTPException)
   where
diff --git a/src/Database/InfluxDB/Query.hs b/src/Database/InfluxDB/Query.hs
--- a/src/Database/InfluxDB/Query.hs
+++ b/src/Database/InfluxDB/Query.hs
@@ -217,11 +217,10 @@
       chunks <- HC.brConsume $ HC.responseBody response
       let body = BL.fromChunks chunks
       case eitherDecode' body of
-        Left message -> throwIO $ UnexpectedResponse message body
+        Left message -> throwIO $ UnexpectedResponse message request body
         Right val -> case A.parse (parseResults (queryPrecision params)) val of
           A.Success vec -> return vec
-          A.Error message ->
-            errorQuery request response message
+          A.Error message -> errorQuery message request response val
 
 setPrecision
   :: Precision 'QueryRequest
@@ -271,7 +270,8 @@
           | B.null chunk = return x
           | otherwise = case k chunk of
             AB.Fail unconsumed _contexts message ->
-              throwIO $ UnexpectedResponse message $ BL.fromStrict unconsumed
+              throwIO $ UnexpectedResponse message request $
+                BL.fromStrict unconsumed
             AB.Partial k' -> do
               chunk' <- HC.responseBody response
               loop x k' chunk'
@@ -280,8 +280,7 @@
                 A.Success vec -> do
                   x' <- step x vec
                   loop x' k0 leftover
-                A.Error message ->
-                  errorQuery request response message
+                A.Error message -> errorQuery message request response val
 
 withQueryResponse
   :: QueryParams
@@ -329,15 +328,17 @@
   where
     Server {..} = queryServer
 
-errorQuery :: HC.Request -> HC.Response body -> String -> IO a
-errorQuery request response message = do
+errorQuery :: String -> HC.Request -> HC.Response body -> A.Value -> IO a
+errorQuery message request response val = do
   let status = HC.responseStatus response
   when (HT.statusIsServerError status) $
     throwIO $ ServerError message
   when (HT.statusIsClientError status) $
     throwIO $ ClientError message request
-  fail $ "BUG: " ++ message ++ " in Database.InfluxDB.Query.query - "
-    ++ show request
+  throwIO $ UnexpectedResponse
+    ("BUG: " ++ message ++ " in Database.InfluxDB.Query.query")
+    request
+    (encode val)
 
 makeLensesWith
   ( lensRules
diff --git a/src/Database/InfluxDB/Types.hs b/src/Database/InfluxDB/Types.hs
--- a/src/Database/InfluxDB/Types.hs
+++ b/src/Database/InfluxDB/Types.hs
@@ -267,12 +267,13 @@
   -- ^ Client side error.
   --
   -- You need to fix your query to get a successful response.
-  | UnexpectedResponse String BL.ByteString
+  | UnexpectedResponse String Request BL.ByteString
   -- ^ Received an unexpected response. The 'String' field is a message and the
-  -- 'BL.ByteString' field is a possibly-empty relevant payload.
+  -- 'BL.ByteString' field is a possibly-empty relevant payload of the response.
   --
   -- This can happen e.g. when the response from InfluxDB is incompatible with
-  -- what this library expects due to an upstream format change etc.
+  -- what this library expects due to an upstream format change or when the JSON
+  -- response doesn't have expected fields etc.
   | HTTPException HC.HttpException
   -- ^ HTTP communication error.
   --
diff --git a/src/Database/InfluxDB/Write.hs b/src/Database/InfluxDB/Write.hs
--- a/src/Database/InfluxDB/Write.hs
+++ b/src/Database/InfluxDB/Write.hs
@@ -143,7 +143,7 @@
         throwIO $ ClientError message request
     else case A.eitherDecode' body of
       Left message ->
-        throwIO $ UnexpectedResponse message body
+        throwIO $ UnexpectedResponse message request body
       Right val -> case A.parse parseErrorObject val of
         A.Success _ ->
           fail $ "BUG: impossible code path in "
@@ -153,9 +153,11 @@
             throwIO $ ServerError message
           when (HT.statusIsClientError status) $
             throwIO $ ClientError message request
-          fail $ "BUG: " ++ message
-            ++ " in Database.InfluxDB.Write.writeByteString"
-
+          throwIO $ UnexpectedResponse
+            ("BUG: " ++ message
+              ++ " in Database.InfluxDB.Write.writeByteString")
+            request
+            (A.encode val)
   where
     request = (writeRequest params)
       { HC.requestBody = HC.RequestBodyLBS payload
