Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework CLI error reporting for the --blockfrost-token-file #3184

Merged
merged 6 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/shelley/cardano-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ library
, bech32
, bech32-th
, binary
, blockfrost-client >=0.3.1.0 && <0.4
, blockfrost-client-core >=0.2.0.0 && <0.3
, blockfrost-api
, blockfrost-client
, blockfrost-client-core
, bytestring
, cardano-addresses
, cardano-api
Expand Down
13 changes: 12 additions & 1 deletion lib/shelley/exe/cardano-wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ import System.Environment
import System.Exit
( ExitCode (..), exitWith )
import UnliftIO.Exception
( withException )
( catch, withException )

import qualified Cardano.BM.Backend.EKGView as EKG
import qualified Cardano.Wallet.Shelley.Launch.Blockfrost as Blockfrost
Expand Down Expand Up @@ -240,6 +240,9 @@ cmdServe = command "serve" $ info (helper <*> helper' <*> cmd) $
pure $ NodeSource conn vData
Light token ->
BlockfrostSource <$> Blockfrost.readToken token
`catch` \(Blockfrost.TokenFileException fp) -> do
logError tr (MsgBlockfrostTokenError fp)
exitWith $ ExitFailure 1

exitWith =<< serveWallet
blockchainSource
Expand All @@ -265,6 +268,7 @@ cmdServe = command "serve" $ info (helper <*> helper' <*> cmd) $
withShutdownHandlerMaybe tr True = void . withShutdownHandler trShutdown
where
trShutdown = trMessage $ contramap (second (fmap MsgShutdownHandler)) tr

{-------------------------------------------------------------------------------
Logging
-------------------------------------------------------------------------------}
Expand All @@ -280,6 +284,7 @@ data MainLog
| MsgSigInt
| MsgShutdownHandler ShutdownHandlerLog
| MsgFailedToParseGenesis Text
| MsgBlockfrostTokenError FilePath
deriving (Show)

instance ToText MainLog where
Expand Down Expand Up @@ -311,6 +316,12 @@ instance ToText MainLog where
, "parameters."
, "Here's (perhaps) some helpful hint:", hint
]
MsgBlockfrostTokenError tokenFile -> T.unwords
[ "File"
, T.pack tokenFile
, "specified in the --blockfrost-token-file\
\ argument doesn't contain a valid Blockfrost API token."
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be nice to have a test against this in BlockfrostSpec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! I'll add some more tests there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added tests for the cases you mentioned above but didn't go as far as testing correspondence between testnet/mainnet environment flag and blockfrost token environment as it would require bigger effort to test several flags in combination.


withTracers
:: LoggingOptions TracerSeverities
Expand Down
32 changes: 28 additions & 4 deletions lib/shelley/src/Cardano/Wallet/Shelley/Launch/Blockfrost.hs
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.Wallet.Shelley.Launch.Blockfrost
( TokenFile
( TokenFile (..)
, readToken
, tokenFileOption
, TokenFileException(..)
) where

import Prelude

import Blockfrost.Client.Core
( projectFromFile )
import Blockfrost.Client.Types
( Project (..) )
import Blockfrost.Env
( parseEnv )
import Control.Exception
( Exception, throw )
import Data.Text
( Text )
import Options.Applicative
( Parser, help, long, metavar, option, str )

import qualified Data.Text as Text
import qualified Data.Text.IO as Text

newtype TokenFile = TokenFile FilePath
deriving newtype (Eq, Show)

newtype TokenFileException = TokenFileException FilePath
deriving stock (Eq, Show)
deriving anyclass (Exception)

-- | --blockfrost-token-file FILE
tokenFileOption :: Parser TokenFile
tokenFileOption = option (TokenFile <$> str) $ mconcat
Expand All @@ -31,4 +45,14 @@ tokenFileOption = option (TokenFile <$> str) $ mconcat
]

readToken :: TokenFile -> IO Project
readToken (TokenFile fp) = projectFromFile fp
readToken (TokenFile fp) = Text.readFile fp >>=
either (throw (TokenFileException fp) . const) pure . mkProject
where
-- Can't use `Blockfrost.Client.Core.projectFromFile` as it uses `error`
-- and it leads to an unnecessary output that pollutes stdout.
mkProject :: Text -> Either Text Project
mkProject t =
let st = Text.strip t
tEnv = Text.dropEnd 32 st
token = Text.drop (Text.length tEnv) st
in Project <$> parseEnv tEnv <*> pure token
1 change: 1 addition & 0 deletions nix/materialized/stack-nix/cardano-wallet.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.