1 module Language.LSP.Test.Exceptions where
3 import Control.Exception
4 import Language.LSP.Types
6 import Data.Aeson.Encode.Pretty
7 import Data.Algorithm.Diff
8 import Data.Algorithm.DiffOutput
10 import qualified Data.ByteString.Lazy.Char8 as B
12 -- | An exception that can be thrown during a 'Haskell.LSP.Test.Session.Session'
13 data SessionException = Timeout (Maybe FromServerMessage)
14 | NoContentLengthHeader
15 | UnexpectedMessage String FromServerMessage
16 | ReplayOutOfOrder FromServerMessage [FromServerMessage]
17 | UnexpectedDiagnostics
18 | IncorrectApplyEditRequest String
19 | UnexpectedResponseError SomeLspId ResponseError
20 | UnexpectedServerTermination
21 | IllegalInitSequenceMessage FromServerMessage
24 instance Exception SessionException
26 instance Show SessionException where
27 show (Timeout lastMsg) =
28 "Timed out waiting to receive a message from the server." ++
30 Just msg -> "\nLast message received:\n" ++ B.unpack (encodePretty msg)
32 show NoContentLengthHeader = "Couldn't read Content-Length header from the server."
33 show (UnexpectedMessage expected lastMsg) =
34 "Received an unexpected message from the server:\n" ++
35 "Was parsing: " ++ expected ++ "\n" ++
36 "But the last message received was:\n" ++ B.unpack (encodePretty lastMsg)
37 show (ReplayOutOfOrder received expected) =
38 let expected' = nub expected
39 getJsonDiff = lines . B.unpack . encodePretty
40 showExp exp = B.unpack (encodePretty exp) ++ "\nDiff:\n" ++
41 ppDiff (getGroupedDiff (getJsonDiff received) (getJsonDiff exp))
42 in "Replay is out of order:\n" ++
43 -- Print json so its a bit easier to update the session logs
44 "Received from server:\n" ++ B.unpack (encodePretty received) ++ "\n" ++
45 "Raw from server:\n" ++ B.unpack (encode received) ++ "\n" ++
46 "Expected one of:\n" ++ unlines (map showExp expected')
47 show UnexpectedDiagnostics = "Unexpectedly received diagnostics from the server."
48 show (IncorrectApplyEditRequest msgStr) = "ApplyEditRequest didn't contain document, instead received:\n"
50 show (UnexpectedResponseError lid e) = "Received an exepected error in a response for id " ++ show lid ++ ":\n"
52 show UnexpectedServerTermination = "Language server unexpectedly terminated"
53 show (IllegalInitSequenceMessage msg) =
54 "Received an illegal message between the initialize request and response:\n"
55 ++ B.unpack (encodePretty msg)
57 -- | A predicate that matches on any 'SessionException'
58 anySessionException :: SessionException -> Bool
59 anySessionException = const True