Segfault upon any JS exception
First of all thank you for this amazing project which has been so useful to us.
Describe the bug
Any exception in the JavaScript code now seems to result in a segfault in the Haskell application when using eval. This did not occur with older versions of inline-js; git bisect reports that the first bad commit is ef675745e84d23d51c50660d40acf9e684fbb2d6 .
To Reproduce Please see reproducer here (uses Nix flakes)
Expected behavior
eval throws an exception instead of causing a segfault.
Environment
- OS name + version: Arch Linux, building under Nix
- Version of the code: master branch commit 0fc7444c552820e44ea54ae82eb1f8542dd56f36
Thanks for this issue, @RichardWarfield! I was about to give up.
Commit 26c89ec30039445d6b3735cb58fda91b38400375 (i.e. the first commit before ef67574) worked like a charm for my project
Even I am getting this issues. Is there a fix other than moving back few commits?
Code to reprduce this.
{-# OPTIONS_GHC -Werror #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import Prelude
import Data.Aeson as A
import GHC.Generics
import Data.Maybe
import Language.JavaScript.Inline
import Data.String
import Data.ByteString.Lazy.Internal as LBS
import Foreign
import Control.Monad
import Control.Exception (try, catch, evaluate, bracketOnError, bracket, SomeException)
data DNSRecord = DNSRecord
{ address :: String
, family :: Int
} deriving (FromJSON, Generic, Show)
dnsLookup :: IO ()
dnsLookup = withDefaultSession $ \s -> do
-- let hs = fromString @EncodedString hostname
v <- eval s [js|
const dns = (await import("dns")).promises;
var v;
v = (ws) => {
throw "SOME-ERROR";
return dns.lookup(ws, {all: true});
}
return v;
|]
let f = importJSFunc s v
putStrLn "NO ERROR"
eiResp :: (Either SomeException Int)
<- try $ do
r <- f (fromString @EncodedString "www.google.com")
putStrLn $ show ((fromMaybe [] $ decode $ getValue r) :: [DNSRecord])
pure 1
case eiResp of
Left ex -> putStrLn $ show ex
Right _ -> putStrLn $ "SUCCESS"
putStrLn "PASSED ERROR"
closeSession s
where
getValue (EncodedJSON a) = a
newFunction :: IO ()
newFunction = withDefaultSession $ \s -> do
v <- eval s [js| () => 6 * 7 |]
let f = importJSFunc s v
r <- f
putStrLn $ show (r :: EncodedJSON)
withDefaultSession :: (Session -> IO a) -> IO a
withDefaultSession = withSession defaultConfig
someFunc :: IO ()
someFunc = do
newFunction
dnsLookup