import qualified Data.ByteString.Lazy.Char8 as B
-- | An exception that can be thrown during a 'Haskell.LSP.Test.Session.Session'
-data SessionException = Timeout
+data SessionException = Timeout (Maybe FromServerMessage)
| NoContentLengthHeader
| UnexpectedMessage String FromServerMessage
| ReplayOutOfOrder FromServerMessage [FromServerMessage]
instance Exception SessionException
instance Show SessionException where
- show Timeout = "Timed out waiting to receive a message from the server."
+ show (Timeout lastMsg) =
+ "Timed out waiting to receive a message from the server." ++
+ case lastMsg of
+ Just msg -> "\nLast message received: " ++ show msg
+ Nothing -> mempty
show NoContentLengthHeader = "Couldn't read Content-Length header from the server."
show (UnexpectedMessage expected lastMsg) =
"Received an unexpected message from the server:\n" ++
curId <- curTimeoutId <$> get
case msg of
ServerMessage sMsg -> yield sMsg
- TimeoutMessage tId -> when (curId == tId) $ throw Timeout
+ TimeoutMessage tId -> when (curId == tId) $ lastReceivedMessage <$> get >>= throw . Timeout
-- | An internal version of 'runSession' that allows for a custom handler to listen to the server.
-- It also does not automatically send initialize and exit messages.
ctx <- ask
-- if its not open, open it
- unless (toNormalizedUri uri `Map.member` (vfsMap oldVFS)) $ do
+ unless (toNormalizedUri uri `Map.member` vfsMap oldVFS) $ do
let fp = fromJust $ uriToFilePath uri
contents <- liftIO $ T.readFile fp
let item = TextDocumentItem (filePathToUri fp) "" 0 contents
getDocumentSymbols doc
-- should now timeout
skipManyTill anyMessage message :: Session ApplyWorkspaceEditRequest
- in sesh `shouldThrow` (== Timeout)
+ isTimeout (Timeout _) = True
+ isTimeout _ = False
+ in sesh `shouldThrow` isTimeout
describe "SessionException" $ do