Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit ac38be3

Browse files
authored
Merge pull request #1220 from Hogeyama/catch-applyrefact-error
Prevent hie crash if apply-refact crashes
2 parents 4afdce5 + ab8d764 commit ac38be3

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

src/Haskell/Ide/Engine/Plugin/ApplyRefact.hs

+14-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ module Haskell.Ide.Engine.Plugin.ApplyRefact where
66

77
import Control.Arrow
88
import Control.Exception ( IOException
9+
, ErrorCall
10+
, Handler(..)
11+
, catches
912
, try
1013
)
1114
import Control.Lens hiding ( List )
@@ -251,10 +254,17 @@ applyHint fp mhint fileMap = do
251254
-- If we provide "applyRefactorings" with "Just (1,13)" then
252255
-- the "Redundant bracket" hint will never be executed
253256
-- because SrcSpan (1,20,??,??) doesn't contain position (1,13).
254-
appliedFile <- liftIO $ applyRefactorings Nothing commands fp
255-
diff <- ExceptT $ Right <$> makeDiffResult fp (T.pack appliedFile) fileMap
256-
liftIO $ logm $ "applyHint:diff=" ++ show diff
257-
return diff
257+
res <- liftIO $ (Right <$> applyRefactorings Nothing commands fp) `catches`
258+
[ Handler $ \e -> return (Left (show (e :: IOException)))
259+
, Handler $ \e -> return (Left (show (e :: ErrorCall)))
260+
]
261+
case res of
262+
Right appliedFile -> do
263+
diff <- ExceptT $ Right <$> makeDiffResult fp (T.pack appliedFile) fileMap
264+
liftIO $ logm $ "applyHint:diff=" ++ show diff
265+
return diff
266+
Left err ->
267+
throwE (show err)
258268

259269
-- | Gets HLint ideas for
260270
getIdeas :: MonadIO m => FilePath -> Maybe OneHint -> ExceptT String m [Idea]

test/testdata/ApplyRefactError.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
foo :: forall a. (a -> a) -> a -> a
2+
foo f x = f $ x

test/unit/ApplyRefactPluginSpec.hs

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
module ApplyRefactPluginSpec where
55

66
import qualified Data.HashMap.Strict as H
7+
import qualified Data.Text as T
78
import Haskell.Ide.Engine.Plugin.ApplyRefact
89
import Haskell.Ide.Engine.MonadTypes
910
import Haskell.Ide.Engine.PluginUtils
@@ -153,3 +154,15 @@ applyRefactSpec = do
153154
, _diagnostics = List []
154155
}
155156
))
157+
158+
-- ---------------------------------
159+
160+
it "reports error without crash" $ do
161+
filePath <- filePathToUri <$> makeAbsolute "./test/testdata/ApplyRefactError.hs"
162+
163+
let req = applyAllCmd' filePath
164+
isExpectedError (IdeResultFail (IdeError PluginError err _)) =
165+
"Illegal symbol '.' in type" `T.isInfixOf` err
166+
isExpectedError _ = False
167+
r <- withCurrentDirectory "./test/testdata" $ runIGM testPlugins req
168+
r `shouldSatisfy` isExpectedError

0 commit comments

Comments
 (0)