From 1d53c7a1d8dd1ea5296f6ce1706ea5edc93d70be Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 9 Feb 2018 22:08:55 +0000 Subject: [PATCH] Properly parse command replies --- src/EuphApi/Connection.hs | 38 +++++++++++++++++++++----------------- src/EuphApi/Types.hs | 2 +- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/EuphApi/Connection.hs b/src/EuphApi/Connection.hs index c08d59f..47c79cf 100644 --- a/src/EuphApi/Connection.hs +++ b/src/EuphApi/Connection.hs @@ -63,6 +63,7 @@ import Control.Concurrent.Async import Control.Concurrent.STM import Control.Monad.Trans.State import Data.Aeson +import Data.Aeson.Types import qualified Data.ByteString.Lazy as BS import qualified Data.HashMap.Strict as HM import qualified Data.Map as M @@ -188,14 +189,17 @@ sendThread euphCon qRecv con = do -} data PacketInfo = PacketInfo - { infoPacketID :: Maybe PacketID - , infoServerError :: Maybe T.Text + { infoPacketID :: Maybe PacketID + , infoData :: Either T.Text Value } deriving (Show) instance FromJSON PacketInfo where parseJSON = withObject "packet" $ \o -> do - infoPacketID <- o .:? "id" - infoServerError <- o .:? "error" + infoPacketID <- o .:? "id" + packetData <- o .:? "data" + infoData <- case packetData of + Nothing -> Left <$> o .: "error" + Just d -> return $ Right d return PacketInfo{..} -- TODO: Swap for HashMap? @@ -217,16 +221,16 @@ processPacket qEvent bs = do PacketInfo{..} <- decode bs replyID <- infoPacketID replyMVar <- M.lookup replyID replies - return (replyID, replyMVar, infoServerError) + return (replyID, replyMVar, infoData) -- ... and then write the appropriate result into the MVar. - whenJust result $ \(replyID, ReplyMVar var, serverError) -> do + whenJust result $ \(replyID, ReplyMVar var, infoData) -> do modify (M.delete replyID) - case serverError of - Just e -> liftIO $ putMVar var (Left (EuphServerError e)) - Nothing -> - case decode bs of - Nothing -> liftIO $ putMVar var (Left EuphParse) - Just r -> liftIO $ putMVar var (Right r) + case infoData of + Left e -> liftIO $ putMVar var (Left (EuphServerError e)) + Right d -> + case parseEither parseJSON d of + Left e -> liftIO $ putMVar var (Left $ EuphParse e bs) + Right r -> liftIO $ putMVar var (Right r) processRecv :: RecvQueue -> EventQueue -> StateT Awaiting IO () processRecv qRecv qEvent = do @@ -436,14 +440,14 @@ data EuphException = EuphClosed -- ^ Disconnected from server while waiting for the reply. | EuphServerError T.Text -- ^ The server replied with an error. - | EuphParse + | EuphParse String BS.ByteString -- ^ Could not parse the server's reply correctly. instance Show EuphException where - show EuphClosed = "Connection already closed" - show EuphDisconnected = "Disconnected from server" - show (EuphServerError t) = "Server error: " ++ T.unpack t - show EuphParse = "Parsing failed" + show EuphClosed = "Connection already closed" + show EuphDisconnected = "Disconnected from server" + show (EuphServerError t) = "Server error: " ++ T.unpack t + show (EuphParse e bs) = "Parsing failed: " ++ e ++ " - packet was " ++ show bs instance Exception EuphException diff --git a/src/EuphApi/Types.hs b/src/EuphApi/Types.hs index 6cffb4d..e5c82ef 100644 --- a/src/EuphApi/Types.hs +++ b/src/EuphApi/Types.hs @@ -84,7 +84,7 @@ data Message = Message -- ^ The unix timestamp of when the message was posted , msgSender :: SessionView -- ^ The view of the sender's session - , msgContent :: String + , msgContent :: T.Text -- ^ The content of the message (client-defined) , msgEdited :: Maybe UTCTime -- ^ The unix timestamp of when the message was last edited