summaryrefslogtreecommitdiff
path: root/haskell/src/SpaceTraders/APIClient/Errors.hs
blob: 2b747847a01226a2a7b7810e7aecee149fda7c81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module SpaceTraders.APIClient.Errors
  ( APIError(..)
  , RateLimit(..)
  , ResetHappened(..)
  ) where

import Control.Exception
import Data.Aeson
import Data.Time
import qualified Data.Text as T
import GHC.Generics

data APIError = APIError Int T.Text Value
              | APIRateLimit RateLimit
              | APIResetHappened ResetHappened
              deriving Show
instance Exception APIError
instance FromJSON APIError where
  parseJSON = withObject "APIError" $ \o -> do
    e <- o .: "error"
    code <- e .: "code"
    d <- e .: "data"
    case code of
      401 -> APIResetHappened <$> parseJSON d
      429 -> APIRateLimit <$> parseJSON d
      _ -> APIError <$> pure code
                    <*> e .: "message"
                    <*> pure d

data RateLimit = RateLimit { limitBurst :: Int
                           , limitPerSecond :: Int
                           , rateLimitType :: T.Text
                           , remaining :: Int
                           , reset :: UTCTime
                           , retryAfter :: Double
                           } deriving Show
instance FromJSON RateLimit where
  parseJSON = withObject "RateLimit" $ \o ->
    RateLimit <$> o .: "limitBurst"
              <*> o .: "limitPerSecond"
              <*> o .: "type"
              <*> o .: "remaining"
              <*> o .: "reset"
              <*> o .: "retryAfter"

data ResetHappened = ResetHappened { actual :: T.Text
                                   , expected :: T.Text
                                   } deriving (FromJSON, Generic, Show, ToJSON)