Исключения в Йесод

93

Я создал демона, который использовал очень примитивную форму ipc(telnet и отправлял строку, содержащую определенные слова в определенном порядке). Я отключился и теперь использую JSONдля передачи сообщений на Yesodсервер. Тем не менее, в моем дизайне мне действительно нравились некоторые вещи, и я не уверен, что могу сделать сейчас.

Вот что я делал:

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

каждая функция в buildSeq выглядела так

foo :: Stage -> ReaderT Config IO ()

data Config = MkConfig (Either JobID Product) BaseDir JobMap

JobMapэто TMVar Mapчто отслеживает информацию о текущей работе.

Итак, у меня есть обработчики, все они выглядят так

foo :: Handler RepJson

foo представляет команду для моего демона, каждый обработчик может обрабатывать другой объект JSON.

Я бы хотел отправить один JSONобъект, представляющий успех, и другой объект JSON, содержащий информацию о каком-то исключении.

Я бы хотел, чтобы fooвспомогательная функция могла возвращать Either, но я не уверен, как я это получаю, плюс возможность прекратить оценку моего списка действий buildSeq.

Вот единственный вариант, который я вижу

1) убедитесь, что он exceptionHandlerнаходится в Handler. Поместите JobMapв Appпротокол. Используя getYesodизмените соответствующее значение для JobMapуказания деталей об исключении, к которым затем может получить доступfoo

Есть ли способ лучше?

Какие у меня другие варианты?

Изменить: для ясности я объясню роль Handler RepJson. Серверу нужен способ принимать такие команды, как build stop report. Клиенту нужен способ узнать результаты этих команд. Я выбрал JSON в качестве среды, с помощью которой сервер и клиент взаимодействуют друг с другом. Я использую тип Handler только для управления входом / выходом JSON и не более того.

Майкл Литчард
источник

Ответы:

9

С философской точки зрения, в мире Haskell / Yesod вы хотите передавать значения вперед, а не возвращать их назад. Поэтому вместо того, чтобы обработчики возвращали значение, пусть они переадресуют вызов следующему этапу процесса, который может вызвать исключение.

Помните, что вы можете объединить любое количество будущих действий в один объект, чтобы вы могли передать объект продолжения своим обработчикам и foos, который в основном говорит им: «После того, как вы закончите, запустите этот blob кода». Таким образом, они могут быть аннулированы и ничего не возвращать.

Тайлер Дерден
источник