Eccezioni in Yesod


93

Avevo creato un demone che utilizzava una forma molto primitiva di ipc(telnet e invia una stringa che aveva determinate parole in un certo ordine). Ne sono uscito e ora lo sto usando JSONper passare i messaggi a un Yesodserver. Tuttavia, c'erano alcune cose che mi sono piaciute molto del mio design e non sono sicuro di quali siano le mie scelte ora.

Ecco cosa stavo facendo:

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 ()

ogni funzione in buildSeq aveva questo aspetto

foo :: Stage -> ReaderT Config IO ()

data Config = MkConfig (Either JobID Product) BaseDir JobMap

JobMapè un TMVar Mapche tiene traccia delle informazioni sui lavori correnti.

quindi ora, quello che ho sono i gestori, che sembrano tutti così

foo :: Handler RepJson

foo rappresenta un comando per il mio daemon, ogni gestore potrebbe dover elaborare un diverso oggetto JSON.

Quello che vorrei fare è inviare un JSONoggetto che rappresenta il successo e un altro oggetto JSON che esprime informazioni su qualche eccezione.

Vorrei foos funzione di supporto per essere in grado di restituire un Either, ma non sono sicuro di come l'ho capito, oltre alla possibilità di interrompere la valutazione del mio elenco di azioni, buildSeq.

Questa è l'unica scelta che vedo

1) assicurati che exceptionHandlersia in Handler. Metti JobMapnel Apprecord. L'utilizzo di getYesodalterare il valore appropriato per JobMapindicare i dettagli sull'eccezione, a cui è quindi possibile accedere dafoo

C'è un modo migliore?

Quali sono le mie altre scelte?

Modifica: per chiarezza, spiegherò il ruolo di Handler RepJson. Il server ha bisogno di un modo per accettare comandi come build stop report. Il client ha bisogno di un modo per conoscere i risultati di questi comandi. Ho scelto JSON come mezzo con cui il server e il client comunicano tra loro. Sto usando il tipo di gestore solo per gestire l'ingresso / uscita JSON e nient'altro.

Risposte:


9

Filosoficamente parlando, nel mondo Haskell / Yesod vuoi trasmettere i valori in avanti, piuttosto che restituirli al contrario. Quindi, invece di fare in modo che i gestori restituiscano un valore, invitali a chiamare in avanti al passaggio successivo del processo, che potrebbe essere quello di generare un'eccezione.

Ricorda che puoi raggruppare qualsiasi quantità di azioni future in un singolo oggetto, in modo da poter passare un oggetto di continuazione ai tuoi gestori e foo che in pratica dice loro: "Dopo aver finito, esegui questo blob di codice". In questo modo possono essere nulli e non restituire nulla.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.