json - Excepciones en Yesod
haskell exception-handling (1)
Hablando filosóficamente, en el mundo de Haskell / Yesod quieres pasar los valores hacia adelante, en lugar de devolverlos hacia atrás. Entonces, en lugar de hacer que los manejadores devuelvan un valor, pídales que lo desvíen al siguiente paso del proceso, que puede ser generar una excepción.
Recuerde que puede agrupar cualquier cantidad de acciones futuras en un solo objeto, para que pueda pasar un objeto de continuación a sus manejadores y foos que básicamente les dice: "Después de que termine, ejecute este bloque de código". De esa manera pueden ser nulos y no devolver nada.
Yo había creado un daemon que usaba una forma muy primitiva de ipc
(telnet y enviaba un String que tenía ciertas palabras en cierto orden). Salí de ella y ahora estoy usando JSON
para pasar mensajes a un servidor de Yesod
. Sin embargo, hubo algunas cosas que realmente me gustaron de mi diseño, y no estoy seguro de cuáles son mis opciones ahora.
Esto es lo que estaba haciendo:
buildManager :: Phase -> IO ()
buildManager phase = do
let buildSeq = findSeq phase
jid = JobID $ pack "8"
config = MkConfig $ Just jid
flip C.catch exceptionHandler $
runReaderT (sequence_ $ buildSeq <*> stages) config
-- ^^ I would really like to keep the above line of code, or something like it.
return ()
cada función en buildSeq se veía así
foo :: Stage -> ReaderT Config IO ()
data Config = MkConfig (Either JobID Product) BaseDir JobMap
JobMap
es un TMVar Map
que rastrea información sobre trabajos actuales.
así que ahora, lo que tengo son controladores, que todos se ven así
foo :: Handler RepJson
foo
representa un comando para mi daemon, cada controlador puede tener que procesar un objeto JSON diferente.
Lo que me gustaría hacer es enviar un objeto JSON
que represente el éxito, y otro objeto JSON que exprese información sobre alguna excepción.
Me gustaría que la función foo
s helper pueda devolver un Either
, pero no estoy seguro de cómo lo consigo, más la capacidad de finalizar la evaluación de mi lista de acciones, buildSeq
.
Esta es la única opción que veo
1) asegúrese de que exceptionHandler
esté en Handler. Coloque JobMap
en el registro de la App
. Usando getYesod
modifique el valor apropiado en JobMap
indicando los detalles sobre la excepción, que luego se puede acceder por foo
¿Hay una mejor manera?
¿Cuáles son mis otras opciones?
Editar: para mayor claridad, explicaré el papel de Handler RepJson
. El servidor necesita alguna forma de aceptar comandos como el report
stop
build
. El cliente necesita alguna forma de conocer los resultados de estos comandos. He elegido JSON como el medio con el que el servidor y el cliente se comunican entre sí. Estoy usando el tipo de controlador solo para administrar la entrada / salida JSON y nada más.