haskell aeson

haskell - ¿Cómo rastrear errores de análisis con Aeson?



(2)

Tengo archivos JSON simples (> 1Mb) grandes para analizar. Utilicé Aeson, siguiendo el tutorial de fpcomplete en su Escuela de Haskell (gracias a todos, por cierto).

Como algunos archivos (y no todos) fallan, sospecho que el archivo json no respeta la estructura que estoy esperando. Los mensajes de error que he recibido hasta ahora han sido

> Failed reading: satisfy

Mi pregunta es :

  • "¿Cómo puedo obtener más detalles sobre lo que salió mal?"

Dos niveles de depuración / registro / rastreo constituyen mis objetivos:

  • identificar el analizador, es decir, qué tipo de datos no se pudo analizar (como para Parsec)
  • Identificando los datos, con un número de línea / char

Desafortunadamente, Aeson intercambia buenos mensajes de error por velocidad. Sin embargo, puede realizar decodificaciones en varias fases, siempre que su estructura JSON sea agradable y el archivo esté fallando en su esquema, y ​​no se analice como JSON por completo.

Por multifase me refiero a decodificar partes de la estructura a la vez. También puede recopilar los valores que fallan para determinar por qué fallaron en su análisis.

parse :: FromJSON a => ByteString -> Maybe [Either Value a] parse s = case decode s of Nothing -> fail "could not decode as array" Just values -> map tryDecode values where tryDecode :: FromJSON a =>Value -> Either Value a tryDecode v = case decode (encode v) of Nothing -> Left v Just a -> Right a

La decode . encode decode . encode bit de decode . encode es bastante ineficiente, ya que se desplaza a través de un ByteString, pero puede mejorarse utilizando los analizadores de Aeson más básicos.


Hay una solución: aeson-better-errors es el buen tutorial del paquete homónimo de Harry Garrood. Este paquete demostró ser tan sencillo de usar como la información que estaba buscando.

Una observación: este paquete no solucionará los errores estructurales, como un corchete faltante. Para ese tipo de errores, sigue recibiendo mensajes InvalidJSON que no están localizados en la secuencia de entrada.