1
0
Fork 0

[haskell] Simplify API Error JSON decoding

This commit is contained in:
Julien Dessaux 2023-07-09 14:31:31 +02:00
parent d829fa5ca2
commit 0f279a06d8
Signed by: adyxax
GPG key ID: F92E51B86E07177E
2 changed files with 16 additions and 24 deletions

View file

@ -11,7 +11,6 @@ module SpaceTraders.APIClient.Client
) where ) where
import Control.Concurrent import Control.Concurrent
import Control.Exception
import Control.Monad import Control.Monad
import Data.Aeson import Data.Aeson
import Data.Aeson.Types import Data.Aeson.Types
@ -48,21 +47,11 @@ send request = do
body = getResponseBody response body = getResponseBody response
if status >= 200 && status <= 299 if status >= 200 && status <= 299
then case eitherDecode body of then case eitherDecode body of
Left e -> return . Left $ APIError (-1000) Null (T.pack $ concat ["Error decoding JSON APIMessage: ", e]) Left e -> return . Left $ APIError (-1000) (T.pack $ concat ["Error decoding JSON APIMessage: ", e]) Null
Right r -> return . Right $ data_ r Right r -> return . Right $ data_ r
else case eitherDecode body of else case eitherDecode body of
Left e -> return . Left $ APIError (-status) Null (T.pack $ concat ["Error decoding JSON APIError: ", e, ". Got HTTP body: ", show body]) Left e -> return . Left $ APIError (-status) (T.pack $ concat ["Error decoding JSON APIError: ", e, ". Got HTTP body: ", show body]) Null
Right e -> case apiErrorCode e of Right (APIRateLimit r) -> do
429 -> do -- We are being rate limited threadDelay (1_000_000 * (round $ retryAfter r))
let d = apiErrorData e
w <- case fromJSONValue d of
Left _ -> throwIO e
Right e' -> return $ retryAfter e'
threadDelay (1_000_000 * (round w))
send request send request
_ -> return $ Left e Right e -> return $ Left e
--handleAPIError :: SomeException -> IO (Maybe RegisterMessage)
--handleAPIError e = do
-- print e
-- return Nothing

View file

@ -11,17 +11,20 @@ import Data.Aeson
import Data.Time import Data.Time
import qualified Data.Text as T import qualified Data.Text as T
data APIError = APIError { apiErrorCode :: Int data APIError = APIError Int T.Text Value
, apiErrorData :: Value | APIRateLimit RateLimit
, apiErrorMessage :: T.Text deriving Show
} deriving Show
instance Exception APIError instance Exception APIError
instance FromJSON APIError where instance FromJSON APIError where
parseJSON (Object o) = do parseJSON (Object o) = do
e <- o .: "error" e <- o .: "error"
APIError <$> e .: "code" code <- e .: "code"
<*> e .: "data" d <- e .: "data"
case code of
429 -> APIRateLimit <$> parseJSON d
_ -> APIError <$> pure code
<*> e .: "message" <*> e .: "message"
<*> pure d
parseJSON _ = mzero parseJSON _ = mzero
data RateLimit = RateLimit { limitBurst :: Int data RateLimit = RateLimit { limitBurst :: Int