Skip to content

Commit 34d4abf

Browse files
committed
Add call stack support in ErrorAsException
1 parent 61b8bf6 commit 34d4abf

File tree

1 file changed

+36
-11
lines changed

1 file changed

+36
-11
lines changed

cardano-api/src/Cardano/Api/Error.hs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
module Cardano.Api.Error
99
( Error (..)
1010
, throwErrorAsException
11+
, liftEitherError
1112
, failEitherError
1213
, ErrorAsException (..)
1314
, FileError (..)
@@ -20,7 +21,8 @@ where
2021
import Cardano.Api.Monad.Error
2122
import Cardano.Api.Pretty
2223

23-
import Control.Exception (Exception (..), IOException, throwIO)
24+
import Control.Exception.Safe
25+
import GHC.Stack
2426
import System.Directory (doesFileExist)
2527
import System.IO (Handle)
2628

@@ -32,26 +34,49 @@ instance Error () where
3234

3335
-- | The preferred approach is to use 'Except' or 'ExceptT', but you can if
3436
-- necessary use IO exceptions.
35-
throwErrorAsException :: Error e => e -> IO a
36-
throwErrorAsException e = throwIO (ErrorAsException e)
37-
38-
failEitherError :: MonadFail m => Error e => Either e a -> m a
37+
throwErrorAsException
38+
:: HasCallStack
39+
=> MonadThrow m
40+
=> Typeable e
41+
=> Error e
42+
=> e
43+
-> m a
44+
throwErrorAsException e = withFrozenCallStack $ throwM $ ErrorAsException e
45+
46+
-- | Pretty print 'Error e' and 'fail' if 'Left'.
47+
failEitherError
48+
:: MonadFail m
49+
=> Error e
50+
=> Either e a
51+
-> m a
3952
failEitherError = failEitherWith displayError
4053

54+
-- | Pretty print 'Error e' and 'throwM' it wrapped in 'ErrorAsException' when 'Left'.
55+
liftEitherError
56+
:: HasCallStack
57+
=> MonadThrow m
58+
=> Typeable e
59+
=> Error e
60+
=> Either e a
61+
-> m a
62+
liftEitherError = withFrozenCallStack $ either throwErrorAsException pure
63+
64+
-- | An exception wrapping any 'Error e', attaching a call stack from the construction place to it.
4165
data ErrorAsException where
42-
ErrorAsException :: Error e => e -> ErrorAsException
66+
ErrorAsException :: (HasCallStack, Typeable e, Error e) => e -> ErrorAsException
67+
68+
instance Exception ErrorAsException
4369

70+
-- | Pretty print the error inside the exception
4471
instance Error ErrorAsException where
4572
prettyError (ErrorAsException e) =
4673
prettyError e
4774

75+
-- | Pretty print the error inside the exception followed by the call stack pointing to the place where 'Error e' was
76+
-- wrapped in 'ErrorAsException'
4877
instance Show ErrorAsException where
4978
show (ErrorAsException e) =
50-
docToString $ prettyError e
51-
52-
instance Exception ErrorAsException where
53-
displayException (ErrorAsException e) =
54-
docToString $ prettyError e
79+
docToString (prettyError e) <> "\n" <> prettyCallStack callStack
5580

5681
displayError :: Error a => a -> String
5782
displayError = docToString . prettyError

0 commit comments

Comments
 (0)