blockfrost-client-core 0.7.0.0 → 0.8.0.0
raw patch · 3 files changed
+56/−14 lines, 3 filesdep +retryPVP ok
version bump matches the API change (PVP)
Dependencies added: retry
API changes (from Hackage documentation)
- Blockfrost.Client.Core: BlockfrostFatal :: Text -> BlockfrostError
+ Blockfrost.Client.Core: retriableError :: BlockfrostError -> RetryAction
- Blockfrost.Client.Core: BlockfrostError :: Text -> BlockfrostError
+ Blockfrost.Client.Core: BlockfrostError :: Status -> Text -> BlockfrostError
Files
- CHANGELOG.md +11/−1
- blockfrost-client-core.cabal +2/−1
- src/Blockfrost/Client/Core.hs +43/−12
CHANGELOG.md view
@@ -1,9 +1,19 @@+# Version [0.8.0.0](https://github.com/blockfrost/blockfrost-haskell/compare/client-core-0.7.0.0...client-core-0.8.0.0) (2026-04-15)++* Changes+ * `BlockfrostError` constructor of `BlockfrostError` type now contains+ `Status` from `Network.HTTP.Types.Status` (HTTP status code and an explanation message).+ Previously `BlockfrostError Text`, now `BlockfrostError Status Text`.+ * `BlockfrostFatal` constructor (HTTP 500) of `BlockfrostError` merged into `BlockfrostError` constructor.+ * `Blockfrost.Client.Core` module now exports `retriableError`, for retry logic+ implemented in `blockfrost-client` package (using `Control.Retry` from `retry` package).+ # Version [0.7.0.0](https://github.com/blockfrost/blockfrost-haskell/compare/client-core-0.6.0.1...client-core-0.7.0.0) (2025-12-02) * Changes * Add `CustomURL` to `Env`, to allow arbitrary Blockfrost instance [#79](https://github.com/blockfrost/blockfrost-haskell/pull/79) * `BlockfrostNotFound` constructor of `BlockfrostError` is now `BlockfrostNotFound Text`- containing path that resulted in 404 error [#80](https://github.com/blockfrost/blockfrost-haskell/pull/80)+ containing path that resulted in 404 error [#81](https://github.com/blockfrost/blockfrost-haskell/pull/81) * Drop `Sanchonet` `Env` [#79](https://github.com/blockfrost/blockfrost-haskell/pull/79) # Version [0.6.0.1](https://github.com/blockfrost/blockfrost-haskell/compare/v0.6.0.0...client-core-0.6.0.1) (2024-01-16)
blockfrost-client-core.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: blockfrost-client-core-version: 0.7.0.0+version: 0.8.0.0 synopsis: blockfrost.io common client definitions / instances description: HasClient for our auth homepage: https://github.com/blockfrost/blockfrost-haskell@@ -54,6 +54,7 @@ , http-client , http-client-tls , http-types+ , retry >= 0.9 && < 0.10 , servant >= 0.18 && < 0.21 , servant-client , servant-client-core
src/Blockfrost/Client/Core.hs view
@@ -1,4 +1,5 @@ -- | Core shared by clients+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-}@@ -7,6 +8,7 @@ module Blockfrost.Client.Core ( BlockfrostError (..)+ , retriableError , Paged (..) , SortOrder (..) , asc@@ -46,6 +48,7 @@ import Servant.Multipart.Client () import qualified System.Environment import Control.Monad.Catch.Pure (runCatch)+import Control.Retry (RetryAction(..)) domain :: String domain = "blockfrost.io"@@ -96,15 +99,14 @@ projectFromFile f = mkProject <$> Data.Text.IO.readFile f data BlockfrostError =- BlockfrostError Text- | BlockfrostBadRequest Text -- 400- | BlockfrostTokenMissing Text -- 403- | BlockfrostNotFound Text -- 404- | BlockfrostIPBanned -- 418- | BlockfrostMempoolFullOrPinQueueFull -- 425- | BlockfrostUsageLimitReached -- 429- | BlockfrostFatal Text -- 500- | ServantClientError ClientError+ BlockfrostError Status Text -- ^ Other HTTP error codes+ | BlockfrostBadRequest Text -- ^ 400+ | BlockfrostTokenMissing Text -- ^ 403+ | BlockfrostNotFound Text -- ^ 404+ | BlockfrostIPBanned -- ^ 418+ | BlockfrostMempoolFullOrPinQueueFull -- ^ 425+ | BlockfrostUsageLimitReached -- ^ 429+ | ServantClientError ClientError -- ^ Unhandled @ClientError@ (either @ConnectionError@ or @DecodeFailure@) deriving (Eq, Show) fromServantClientError :: ClientError -> BlockfrostError@@ -126,16 +128,45 @@ BlockfrostMempoolFullOrPinQueueFull | s == status429 -> BlockfrostUsageLimitReached- | s == status500 ->- BlockfrostFatal (withMessage body) | otherwise ->- BlockfrostError (withMessage body)+ BlockfrostError s (withMessage body) _ -> ServantClientError e where withMessage body = case eitherDecode body of (Right (ae :: ApiError)) -> apiErrorMessage ae _ -> mempty++retriableError :: BlockfrostError -> RetryAction+retriableError BlockfrostIPBanned+ = ConsultPolicyOverrideDelay (5 * 60 * 1000 * 1000) -- 5 minutes+retriableError BlockfrostMempoolFullOrPinQueueFull+ = ConsultPolicy+retriableError BlockfrostUsageLimitReached+ = ConsultPolicyOverrideDelay (5 * 60 * 1000 * 1000) -- 5 minutes+retriableError (BlockfrostError s _) =+ (\case+ True -> ConsultPolicy+ False -> DontRetry+ )+ . elem+ s+ $ [ requestTimeout408+ , internalServerError500+ , badGateway502+ , serviceUnavailable503+ , gatewayTimeout504+ ]+ -- CF reverse proxy+ ++ map+ (flip mkStatus mempty)+ [ 520+ , 521+ , 522+ , 524+ ]+retriableError (ServantClientError (ConnectionError _)) = ConsultPolicy+retriableError _ = DontRetry instance ToMultipart Tmp Form where toMultipart (Form fileName filePath) =