Мой тип и коррекция реализации FromJSON, как указано ниже.Как правильно вывести ошибку в анализе JSON с помощью Data.Aeson
nonEmpty
поворачивает List
в Maybe NonEmpty
, и я пытаюсь правильно иметь дело со случаем, когда List
действительно пуст, и я должен прервать разбор. Этот синтаксический анализ фактически выполняется внутри parseJsonBody
, что означает, что я не хочу error "foo"
мой выход из него, но я хочу вернуть mzero
(или что-то еще сделает трюк, mzero
- единственное, на что я наткнулся, далеко), чтобы обработчик правильно возвращал 400 вместо аварийного с 500.
Подход ниже компилируется, но, насколько я могу судить, в значительной степени равен error
или какой-либо другой форме исключения, бросающей внутрь parseJSON , Однако, если я возвращаю mzero
(например, с помощью <*> mzero
вместо этой строки), это не так хорошо, как предполагалось.
import qualified Data.List.NonEmpty as NE
data GSAnswer = GSAnswer { gsAnswerQuestionId :: Int
, gsAnswerResponses :: NE.NonEmpty GSResponse
} deriving (Show, Eq)
instance FromJSON GSAnswer where
parseJSON (Object o) =
GSAnswer <$> o .: "question-id"
-- how do I return mzero here based on NE.nonEmpty?
-- this will throw an exception right now on an empty list
<*> fmap (fromMaybe (fail "foo") . NE.nonEmpty) (o .: "responses")
parseJSON _ = mzero
Одним из вариантов было бы как-то шаблон матча на результат fmap NE.nonEmpty (o .: "responses")
, но я не могу вполне понять, что картина будет там: не выглядит как Parser имеет никаких конструкторов?
Кажется, сделать трюк, спасибо. Любые предложения относительно того, как добавить конкретное сообщение об ошибке к сбою Parser? В настоящее время сообщенное сообщение об ошибке «mzero», было бы аккуратно, если бы я мог передать свое собственное сообщение об ошибке, потому что Parser пришлось прервать. –
Вы пробовали 'fail 'msg" 'вместо' mzero' в трансформаторе? Я сейчас не на своем ПК, но я могу проверить позже. – Zeta
Это похоже на трюк, спасибо, я изменил приведенное выше: toNonEmptyP :: String -> Parser [a] -> Parser (NE.NonEmpty a) toNonEmptyP msg p = fmap NE.nonEmpty p >> = возможно (сбой msg) return –