{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Text.Pandoc.Lua.ErrorConversion
( errorConversion
) where
import Foreign.Lua (Lua (..), NumResults)
import Text.Pandoc.Error (PandocError (PandocLuaError))
import Text.Pandoc.Lua.Marshaling.PandocError (pushPandocError, peekPandocError)
import qualified Control.Monad.Catch as Catch
import qualified Data.Text as T
import qualified Foreign.Lua as Lua
errorConversion :: Lua.ErrorConversion
errorConversion = Lua.ErrorConversion
{ Lua.addContextToException = addContextToException
, Lua.alternative = alternative
, Lua.errorToException = errorToException
, Lua.exceptionToError = exceptionToError
}
errorToException :: forall a . Lua.State -> IO a
errorToException l = Lua.unsafeRunWith l $ do
err <- peekPandocError Lua.stackTop
Lua.pop 1
Catch.throwM err
alternative :: forall a . Lua a -> Lua a -> Lua a
alternative x y = Catch.try x >>= \case
Left (_ :: PandocError) -> y
Right x' -> return x'
addContextToException :: forall a . String -> Lua a -> Lua a
addContextToException ctx op = op `Catch.catch` \case
PandocLuaError msg -> Catch.throwM $ PandocLuaError (T.pack ctx <> msg)
e -> Catch.throwM e
exceptionToError :: Lua NumResults -> Lua NumResults
exceptionToError op = op `Catch.catch` \e -> do
pushPandocError e
Lua.error