calamity 0.1.14.4 → 0.1.14.5
raw patch · 8 files changed
+54/−30 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Calamity.HTTP.Internal.Types: DecodeError :: Text -> RestError
+ Calamity.HTTP.Internal.Types: InternalClientError :: Text -> RestError
+ Calamity.HTTP.Internal.Types: InternalResponseError :: Text -> DiscordResponseType
- Calamity.Cache.Eff: delDM :: forall r_a9wBm. MemberWithError CacheEff r_a9wBm => Snowflake DMChannel -> Sem r_a9wBm ()
+ Calamity.Cache.Eff: delDM :: forall r_a9wF3. MemberWithError CacheEff r_a9wF3 => Snowflake DMChannel -> Sem r_a9wF3 ()
- Calamity.Cache.Eff: delGuild :: forall r_a9wBf. MemberWithError CacheEff r_a9wBf => Snowflake Guild -> Sem r_a9wBf ()
+ Calamity.Cache.Eff: delGuild :: forall r_a9wEW. MemberWithError CacheEff r_a9wEW => Snowflake Guild -> Sem r_a9wEW ()
- Calamity.Cache.Eff: delMessage :: forall r_a9wBH. MemberWithError CacheEff r_a9wBH => Snowflake Message -> Sem r_a9wBH ()
+ Calamity.Cache.Eff: delMessage :: forall r_a9wFo. MemberWithError CacheEff r_a9wFo => Snowflake Message -> Sem r_a9wFo ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9wBA. MemberWithError CacheEff r_a9wBA => Snowflake Guild -> Sem r_a9wBA ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9wFh. MemberWithError CacheEff r_a9wFh => Snowflake Guild -> Sem r_a9wFh ()
- Calamity.Cache.Eff: delUser :: forall r_a9wBt. MemberWithError CacheEff r_a9wBt => Snowflake User -> Sem r_a9wBt ()
+ Calamity.Cache.Eff: delUser :: forall r_a9wFa. MemberWithError CacheEff r_a9wFa => Snowflake User -> Sem r_a9wFa ()
- Calamity.Cache.Eff: getBotUser :: forall r_a9wB7. MemberWithError CacheEff r_a9wB7 => Sem r_a9wB7 (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a9wEO. MemberWithError CacheEff r_a9wEO => Sem r_a9wEO (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a9wBj. MemberWithError CacheEff r_a9wBj => Snowflake DMChannel -> Sem r_a9wBj (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a9wF0. MemberWithError CacheEff r_a9wF0 => Snowflake DMChannel -> Sem r_a9wF0 (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a9wBl. MemberWithError CacheEff r_a9wBl => Sem r_a9wBl [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a9wF2. MemberWithError CacheEff r_a9wF2 => Sem r_a9wF2 [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a9wBa. MemberWithError CacheEff r_a9wBa => Snowflake Guild -> Sem r_a9wBa (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a9wER. MemberWithError CacheEff r_a9wER => Snowflake Guild -> Sem r_a9wER (Maybe Guild)
- Calamity.Cache.Eff: getGuildChannel :: forall r_a9wBc. MemberWithError CacheEff r_a9wBc => Snowflake GuildChannel -> Sem r_a9wBc (Maybe GuildChannel)
+ Calamity.Cache.Eff: getGuildChannel :: forall r_a9wET. MemberWithError CacheEff r_a9wET => Snowflake GuildChannel -> Sem r_a9wET (Maybe GuildChannel)
- Calamity.Cache.Eff: getGuilds :: forall r_a9wBe. MemberWithError CacheEff r_a9wBe => Sem r_a9wBe [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a9wEV. MemberWithError CacheEff r_a9wEV => Sem r_a9wEV [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a9wBE. MemberWithError CacheEff r_a9wBE => Snowflake Message -> Sem r_a9wBE (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a9wFl. MemberWithError CacheEff r_a9wFl => Snowflake Message -> Sem r_a9wFl (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a9wBG. MemberWithError CacheEff r_a9wBG => Sem r_a9wBG [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a9wFn. MemberWithError CacheEff r_a9wFn => Sem r_a9wFn [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9wBz. MemberWithError CacheEff r_a9wBz => Sem r_a9wBz [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9wFg. MemberWithError CacheEff r_a9wFg => Sem r_a9wFg [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a9wBq. MemberWithError CacheEff r_a9wBq => Snowflake User -> Sem r_a9wBq (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a9wF7. MemberWithError CacheEff r_a9wF7 => Snowflake User -> Sem r_a9wF7 (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a9wBs. MemberWithError CacheEff r_a9wBs => Sem r_a9wBs [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a9wF9. MemberWithError CacheEff r_a9wF9 => Sem r_a9wF9 [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9wBx. MemberWithError CacheEff r_a9wBx => Snowflake Guild -> Sem r_a9wBx Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9wFe. MemberWithError CacheEff r_a9wFe => Snowflake Guild -> Sem r_a9wFe Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a9wB5. MemberWithError CacheEff r_a9wB5 => User -> Sem r_a9wB5 ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a9wEM. MemberWithError CacheEff r_a9wEM => User -> Sem r_a9wEM ()
- Calamity.Cache.Eff: setDM :: forall r_a9wBh. MemberWithError CacheEff r_a9wBh => DMChannel -> Sem r_a9wBh ()
+ Calamity.Cache.Eff: setDM :: forall r_a9wEY. MemberWithError CacheEff r_a9wEY => DMChannel -> Sem r_a9wEY ()
- Calamity.Cache.Eff: setGuild :: forall r_a9wB8. MemberWithError CacheEff r_a9wB8 => Guild -> Sem r_a9wB8 ()
+ Calamity.Cache.Eff: setGuild :: forall r_a9wEP. MemberWithError CacheEff r_a9wEP => Guild -> Sem r_a9wEP ()
- Calamity.Cache.Eff: setMessage :: forall r_a9wBC. MemberWithError CacheEff r_a9wBC => Message -> Sem r_a9wBC ()
+ Calamity.Cache.Eff: setMessage :: forall r_a9wFj. MemberWithError CacheEff r_a9wFj => Message -> Sem r_a9wFj ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9wBv. MemberWithError CacheEff r_a9wBv => Snowflake Guild -> Sem r_a9wBv ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9wFc. MemberWithError CacheEff r_a9wFc => Snowflake Guild -> Sem r_a9wFc ()
- Calamity.Cache.Eff: setUser :: forall r_a9wBo. MemberWithError CacheEff r_a9wBo => User -> Sem r_a9wBo ()
+ Calamity.Cache.Eff: setUser :: forall r_a9wF5. MemberWithError CacheEff r_a9wF5 => User -> Sem r_a9wF5 ()
- Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a79Nd. MemberWithError ParsePrefix r_a79Nd => Message -> Sem r_a79Nd (Maybe (Text, Text))
+ Calamity.Commands.ParsePrefix: parsePrefix :: forall r_a79QD. MemberWithError ParsePrefix r_a79QD => Message -> Sem r_a79QD (Maybe (Text, Text))
- Calamity.Internal.LocalWriter: llisten :: forall o_aEF8 r_aEV8 a_XEF8. MemberWithError (LocalWriter o_aEF8) r_aEV8 => Sem r_aEV8 a_XEF8 -> Sem r_aEV8 (o_aEF8, a_XEF8)
+ Calamity.Internal.LocalWriter: llisten :: forall o_aEFh r_aEVh a_XEFh. MemberWithError (LocalWriter o_aEFh) r_aEVh => Sem r_aEVh a_XEFh -> Sem r_aEVh (o_aEFh, a_XEFh)
- Calamity.Internal.LocalWriter: ltell :: forall o_aEF4 r_aEV6. MemberWithError (LocalWriter o_aEF4) r_aEV6 => o_aEF4 -> Sem r_aEV6 ()
+ Calamity.Internal.LocalWriter: ltell :: forall o_aEFd r_aEVf. MemberWithError (LocalWriter o_aEFd) r_aEVf => o_aEFd -> Sem r_aEVf ()
- Calamity.Internal.RunIntoIO: intoIO :: forall p_aFYH r_aFYJ r_aG3O. MemberWithError (IntoIO p_aFYH r_aFYJ) r_aG3O => (p_aFYH -> Sem r_aG3O r_aFYJ) -> Sem r_aG3O (p_aFYH -> IO (Maybe r_aFYJ))
+ Calamity.Internal.RunIntoIO: intoIO :: forall p_aFYQ r_aFYS r_aG3X. MemberWithError (IntoIO p_aFYQ r_aFYS) r_aG3X => (p_aFYQ -> Sem r_aG3X r_aFYS) -> Sem r_aG3X (p_aFYQ -> IO (Maybe r_aFYS))
- Calamity.Metrics.Eff: addCounter :: forall r_aIKY. MemberWithError MetricEff r_aIKY => Int -> Counter -> Sem r_aIKY Int
+ Calamity.Metrics.Eff: addCounter :: forall r_aIL7. MemberWithError MetricEff r_aIL7 => Int -> Counter -> Sem r_aIL7 Int
- Calamity.Metrics.Eff: modifyGauge :: forall r_aIL1. MemberWithError MetricEff r_aIL1 => (Double -> Double) -> Gauge -> Sem r_aIL1 Double
+ Calamity.Metrics.Eff: modifyGauge :: forall r_aILa. MemberWithError MetricEff r_aILa => (Double -> Double) -> Gauge -> Sem r_aILa Double
- Calamity.Metrics.Eff: observeHistogram :: forall r_aIL4. MemberWithError MetricEff r_aIL4 => Double -> Histogram -> Sem r_aIL4 HistogramSample
+ Calamity.Metrics.Eff: observeHistogram :: forall r_aILd. MemberWithError MetricEff r_aILd => Double -> Histogram -> Sem r_aILd HistogramSample
- Calamity.Metrics.Eff: registerCounter :: forall r_aIKO. MemberWithError MetricEff r_aIKO => Text -> [(Text, Text)] -> Sem r_aIKO Counter
+ Calamity.Metrics.Eff: registerCounter :: forall r_aIKX. MemberWithError MetricEff r_aIKX => Text -> [(Text, Text)] -> Sem r_aIKX Counter
- Calamity.Metrics.Eff: registerGauge :: forall r_aIKR. MemberWithError MetricEff r_aIKR => Text -> [(Text, Text)] -> Sem r_aIKR Gauge
+ Calamity.Metrics.Eff: registerGauge :: forall r_aIL0. MemberWithError MetricEff r_aIL0 => Text -> [(Text, Text)] -> Sem r_aIL0 Gauge
- Calamity.Metrics.Eff: registerHistogram :: forall r_aIKU. MemberWithError MetricEff r_aIKU => Text -> [(Text, Text)] -> [Double] -> Sem r_aIKU Histogram
+ Calamity.Metrics.Eff: registerHistogram :: forall r_aIL3. MemberWithError MetricEff r_aIL3 => Text -> [(Text, Text)] -> [Double] -> Sem r_aIL3 Histogram
Files
- ChangeLog.md +9/−0
- calamity.cabal +2/−2
- src/Calamity/HTTP/Internal/Ratelimit.hs +33/−21
- src/Calamity/HTTP/Internal/Request.hs +2/−2
- src/Calamity/HTTP/Internal/Route.hs +1/−1
- src/Calamity/HTTP/Internal/Types.hs +4/−1
- src/Calamity/HTTP/User.hs +1/−1
- src/Calamity/HTTP/Webhook.hs +2/−2
ChangeLog.md view
@@ -1,5 +1,14 @@ # Changelog for Calamity +## 0.1.14.5++*2020-06-18*++* The `DecodeError` variant of the `RestError` type has been renamed to+ `InternalClientError` as all issues in the rest client now end up here.+ +* We're now using `discord.com` instead of `discordapp.com`+ ## 0.1.14.4 *2020-06-11*
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: f4c6fde3ae6f429b22eea33179e85d448bc6d821e6d0e78fdfa8bd664dc74dc5+-- hash: e8f0d2b37e6993b5feabb3a7bc1bd424330c236f6d3d984c68336bdf840118ba name: calamity-version: 0.1.14.4+version: 0.1.14.5 synopsis: A library for writing discord bots description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web
src/Calamity/HTTP/Internal/Ratelimit.hs view
@@ -23,6 +23,7 @@ import qualified Data.ByteString.Lazy as LB import Data.Functor import Data.Maybe+import qualified Data.Text.Lazy as LT import Data.Time import Data.Time.Clock.POSIX @@ -41,6 +42,7 @@ import Prelude hiding ( error ) import qualified StmContainers.Map as SC+import qualified Control.Exception.Safe as Ex newRateLimitState :: IO RateLimitState newRateLimitState = RateLimitState <$> SC.newIO <*> E.newSet@@ -56,28 +58,34 @@ doDiscordRequest :: BotC r => IO (Response LB.ByteString) -> Sem r DiscordResponseType doDiscordRequest r = do- r' <- P.embed r- let status = r' ^. responseStatus- if- | statusIsSuccessful status -> do- let resp = r' ^. responseBody- debug $ "Got good response from discord: " +|| r' ^. responseStatus ||+ ""- pure $ if isExhausted r'- then ExhaustedBucket resp $ parseRateLimitHeader r'- else Good resp- | status == status429 -> do- debug "Got 429 from discord, retrying."- case asValue r' of- Just rv -> pure $ Ratelimited (parseRetryAfter rv) (isGlobal rv)- Nothing -> pure $ ClientError (status ^. statusCode) "429 with invalid json???"- | statusIsClientError status -> do- let err = r' ^. responseBody- error $ "Something went wrong: " +|| err ||+ " response: " +|| r' ||+ ""- pure $ ClientError (status ^. statusCode) err- | otherwise -> do- debug $ "Got server error from discord: " +| status ^. statusCode |+ ""- pure $ ServerError (status ^. statusCode)+ r'' <- P.embed $ Ex.catchAny (Right <$> r) (pure . Left . Ex.displayException)+ case r'' of+ Right r' -> do+ let status = r' ^. responseStatus+ if+ | statusIsSuccessful status -> do+ let resp = r' ^. responseBody+ debug $ "Got good response from discord: " +|| r' ^. responseStatus ||+ ""+ pure $ if isExhausted r'+ then ExhaustedBucket resp $ parseRateLimitHeader r'+ else Good resp+ | status == status429 -> do+ debug "Got 429 from discord, retrying."+ case asValue r' of+ Just rv -> pure $ Ratelimited (parseRetryAfter rv) (isGlobal rv)+ Nothing -> pure $ ClientError (status ^. statusCode) "429 with invalid json???"+ | statusIsClientError status -> do+ let err = r' ^. responseBody+ error $ "Something went wrong: " +|| err ||+ " response: " +|| r' ||+ ""+ pure $ ClientError (status ^. statusCode) err+ | otherwise -> do+ debug $ "Got server error from discord: " +| status ^. statusCode |+ ""+ pure $ ServerError (status ^. statusCode)+ Left e -> do+ error $ "Something went wrong with the http client: " +| LT.pack e |+ ""+ pure . InternalResponseError $ LT.pack e + parseDiscordTime :: ByteString -> Maybe UTCTime parseDiscordTime s = httpDateToUTC <$> parseHTTPDate s @@ -172,6 +180,10 @@ ServerError c -> do debug "Server failed, retrying" pure $ Retry (HTTPError c Nothing)++ InternalResponseError c -> do+ debug "Internal error, retrying"+ pure $ Retry (InternalClientError c) ClientError c v -> pure $ RFail (HTTPError c $ decode v)
src/Calamity/HTTP/Internal/Request.hs view
@@ -40,11 +40,11 @@ fromResult :: P.Member (P.Error RestError) r => Data.Aeson.Result a -> Sem r a fromResult (Success a) = pure a-fromResult (Error e) = P.throw (DecodeError . TL.pack $ e)+fromResult (Error e) = P.throw (InternalClientError . TL.pack $ e) fromJSONDecode :: P.Member (P.Error RestError) r => Either String a -> Sem r a fromJSONDecode (Right a) = pure a-fromJSONDecode (Left e) = P.throw (DecodeError . TL.pack $ e)+fromJSONDecode (Left e) = P.throw (InternalClientError . TL.pack $ e) extractRight :: P.Member (P.Error e) r => Either e a -> Sem r a extractRight (Left e) = P.throw e
src/Calamity/HTTP/Internal/Route.hs view
@@ -125,7 +125,7 @@ hashWithSalt s (Route _ ident c g) = hashWithSalt s (ident, c, g) baseURL :: Text-baseURL = "https://discordapp.com/api/v7"+baseURL = "https://discord.com/api/v7" buildRoute :: forall (ids :: [(Type, RouteRequirement)])
src/Calamity/HTTP/Internal/Types.hs view
@@ -21,11 +21,13 @@ import qualified StmContainers.Map as SC data RestError+ -- | An error response from discord = HTTPError { status :: Int , response :: Maybe Value }- | DecodeError Text+ -- | Something failed while making the request (after retrying a few times)+ | InternalClientError Text deriving ( Show, Generic ) data RateLimitState = RateLimitState@@ -43,6 +45,7 @@ Bool -- ^ Global ratelimit | ServerError Int -- ^ Discord's error, we should retry (HTTP 5XX) | ClientError Int LB.ByteString -- ^ Our error, we should fail+ | InternalResponseError Text -- ^ Something went wrong with the http client newtype GatewayResponse = GatewayResponse { url :: Text
src/Calamity/HTTP/User.hs view
@@ -28,7 +28,7 @@ data ModifyUserData = ModifyUserData { username :: Maybe Text- -- | The avatar field should be in discord's image data format: https://discordapp.com/developers/docs/reference#image-data+ -- | The avatar field should be in discord's image data format: https://discord.com/developers/docs/reference#image-data , avatar :: Maybe Text } deriving ( Show, Generic, Default )
src/Calamity/HTTP/Webhook.hs view
@@ -29,7 +29,7 @@ data CreateWebhookData = CreateWebhookData { username :: Maybe Text- -- | The avatar field should be in discord's image data format: https://discordapp.com/developers/docs/reference#image-data+ -- | The avatar field should be in discord's image data format: https://discord.com/developers/docs/reference#image-data , avatar :: Maybe Text } deriving ( Show, Generic, Default )@@ -37,7 +37,7 @@ data ModifyWebhookData = ModifyWebhookData { username :: Maybe Text- -- | The avatar field should be in discord's image data format: https://discordapp.com/developers/docs/reference#image-data+ -- | The avatar field should be in discord's image data format: https://discord.com/developers/docs/reference#image-data , avatar :: Maybe Text , channelID :: Maybe (Snowflake Channel) }