Skip to content

Commit be1580f

Browse files
authored
Display FFI errors to user (#268)
1 parent a989a85 commit be1580f

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Bugfixes:
1313
Other improvements:
1414

1515
- Use `replaceState` for setting query params (#266 by @ptrfrncsmrph)
16+
- Display missing FFI dependency error message to user (#268 by @ptrfrncsmrph)
1617

1718
## [v2021-11-30.1](https://github.com/purescript/trypurescript/releases/tag/v2021-11-11.1)
1819

client/public/css/index.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ pre code {
221221
background: none;
222222
border: 0;
223223
margin: 0;
224+
overflow-x: auto;
225+
white-space: pre-wrap;
226+
white-space: -moz-pre-wrap;
227+
white-space: -pre-wrap;
228+
white-space: -o-pre-wrap;
229+
word-wrap: break-word;
224230
}
225231

226232
iframe {

client/src/Try/Container.purs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Ace (Annotation)
66
import Control.Monad.Except (runExceptT)
77
import Data.Array (fold)
88
import Data.Array as Array
9-
import Data.Either (Either(..), hush)
9+
import Data.Either (Either(..))
1010
import Data.Foldable (for_, oneOf)
1111
import Data.FoldableWithIndex (foldMapWithIndex)
1212
import Data.Maybe (Maybe(..), fromMaybe, isNothing)
@@ -189,17 +189,22 @@ component = H.mkComponent
189189
if settings.showJs then
190190
H.liftEffect teardownIFrame
191191
else do
192-
mbSources <- H.liftAff $ map hush $ runExceptT $ runLoader loader (JS js)
192+
eitherSources <- H.liftAff $ runExceptT $ runLoader loader (JS js)
193193
for_ warnings \warnings_ -> do
194194
let anns = Array.mapMaybe (toAnnotation MarkerWarning) warnings_
195195
_ <- H.query _editor unit $ H.tell $ Editor.SetAnnotations anns
196196
pure unit
197-
for_ mbSources \sources -> do
198-
let eventData = Object.insert "<file>" (JS js) sources
199-
H.liftAff $ makeAff \f -> do
200-
runEffectFn3 setupIFrame eventData (f (Right unit)) (f (Left $ Aff.error "Could not load iframe"))
201-
mempty
202-
H.modify_ _ { compiled = Just (Right res) }
197+
case eitherSources of
198+
Right sources -> do
199+
let eventData = Object.insert "<file>" (JS js) sources
200+
H.liftAff $ makeAff \f -> do
201+
runEffectFn3 setupIFrame eventData (f (Right unit)) (f (Left $ Aff.error "Could not load iframe"))
202+
mempty
203+
H.modify_ _ { compiled = Just (Right res) }
204+
Left err -> do
205+
H.liftEffect teardownIFrame
206+
H.liftEffect $ error err
207+
H.modify_ _ { compiled = Just (Left err) }
203208

204209
HandleEditor (Editor.TextChanged text) -> do
205210
_ <- H.fork $ handleAction $ Cache text
@@ -383,7 +388,7 @@ component = H.mkComponent
383388

384389
renderCompiled = case _ of
385390
Left err ->
386-
renderPlaintext "Unable to parse the response from the server."
391+
renderPlaintext err
387392
Right res -> case res of
388393
CompileFailed { error } -> case error of
389394
OtherError err ->

client/src/Try/Loader.purs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ module Try.Loader
77
import Prelude
88

99
import Control.Bind (bindFlipped)
10-
import Control.Monad.Except (ExceptT)
10+
import Control.Monad.Except (ExceptT, throwError)
1111
import Control.Parallel (parTraverse)
12+
import Data.Array (foldMap)
1213
import Data.Array as Array
1314
import Data.Array.NonEmpty as NonEmpty
1415
import Data.Maybe (Maybe(..), fromMaybe)
1516
import Data.Newtype (unwrap)
16-
import Data.String (Pattern(..))
17+
import Data.String (Pattern(..), joinWith)
1718
import Data.String as String
1819
import Data.String.Regex (Regex)
1920
import Data.String.Regex as Regex
@@ -112,10 +113,20 @@ makeLoader rootPath = Loader (go Object.empty <<< parseDeps "<file>")
112113
deps = { name: _, path: Nothing } <$> shim.deps
113114
pure { name, path, deps, src }
114115
Nothing ->
115-
pure { name, path, deps: [], src: ffiDep name }
116+
throwError (missingFFIDep name)
116117
liftEffect $ putModule name mod
117118
pure mod
118119

120+
missingFFIDep :: String -> String
121+
missingFFIDep name =
122+
joinWith "\n" $
123+
[ "Compilation succeeded, but the following FFI dependency is missing:"
124+
, " - " <> name
125+
, ""
126+
, "We don't provide FFI shims for all libraries; for example, Node libraries are not supported on Try PureScript."
127+
, "If you would like to suggest a new FFI shim be supported, please open an issue."
128+
]
129+
119130
go :: Object JS -> Array Dependency -> ExceptT String Aff (Object JS)
120131
go ms [] = pure ms
121132
go ms deps = do
@@ -130,6 +141,3 @@ makeLoader rootPath = Loader (go Object.empty <<< parseDeps "<file>")
130141
# bindFlipped _.deps
131142
# Array.nubBy (comparing _.name)
132143
# go ms'
133-
134-
ffiDep :: String -> JS
135-
ffiDep name = JS $ "throw new Error('FFI dependency not provided: " <> name <> "');"

0 commit comments

Comments
 (0)