Estoy implementando un REPL para un intérprete Scheme en Haskell y me gustaría manejar algunos eventos asincrónicos como UserInterrupt, StackOverflow, HeapOverflow, etc. Básicamente, me gustaría detener el cómputo actual cuando se produce UserInterrupt e imprimir un mensaje adecuado cuando se producen Stackoverflow y desbordamiento de montículo, etc. he implementado de la siguiente manera:Manejo de la excepción de UserInterrupt en Haskell
repl evaluator = forever $ (do
putStr ">>> " >> hFlush stdout
out <- getLine >>= evaluator
if null out
then return()
else putStrLn out)
`catch`
onUserInterrupt
onUserInterrupt UserInterrupt = putStrLn "\nUserInterruption"
onUserInterrupt e = throw e
main = do
interpreter <- getMyLispInterpreter
handle onAbort (repl $ interpreter "stdin")
putStrLn "Exiting..."
onAbort e = do
let x = show (e :: SomeException)
putStrLn $ "\nAborted: " ++ x
funciona como se esperaba, con una excepción. Si inicio el intérprete y presiono Ctrl + Z + Entrar, obtengo:
>>> ^Z
Aborted: <stdin>: hGetLine: end of file
Exiting...
Correcto. Pero si comienzo el intérprete y pulse Ctrl-C seguido de Ctrl-Z + Enter consigo:
>>>
UserInterruption
>>> ^Z
Y se cuelga y no puedo usar el intérprete más. Sin embargo, si presiono Ctrl-C nuevamente, el REPL se desbloquea. Busqué mucho y no puedo entender el motivo. ¿Alguien puede explicarme?
¡Muchas gracias!
Nunca veo Ctrl-Z ser atrapado. Se captura la primera Ctrl-C, pero la segunda no. Ese es probablemente el mismo problema. ¿Podría cambiar su código en un testcase de trabajo completo? F.e. 'return' en lugar de 'interpreter' stdin '' y con las importaciones apropiadas agregadas. –