haskellari / postgresql-simple

Mid-level client library for accessing PostgreSQL from Haskell
Other
84 stars 43 forks source link

ConveresionFailed error - how to get the row anyways? #140

Closed CGenie closed 6 days ago

CGenie commented 6 days ago

Hello,

I'm trying to wrap the pgmq queue system into Haskell.

Basically, one issues a query of form SELECT * FROM pgmq.read('some_queue', 0, 1) and it returns a table with fields like id, enqueued_at and message. The message is of jsonb type.

I want to be safe and, in case I cannot parse the jsonb, I would like to archive that row (calling select pgmq.archive('some_queue', <id>).

However, the error: https://hackage.haskell.org/package/postgresql-simple-0.7.0.0/docs/Database-PostgreSQL-Simple.html#v:ConversionFailed only returns data local to the given field.

Is there a way to recover the row that failed with ConversionFailed, so I can get into that id field and remove the failing message?

Thing is, I cannot call select pgmq.read the second time, because I might get a different message. And that row must contain some valid JSON because it's of jsonb type in postgres, it's just the Haskell parser doesn't like it.

phadej commented 6 days ago

And that row must contain some valid JSON because it's of jsonb type in postgres, it's just the Haskell parser doesn't like it.

Than that is a bug in postgresql-simple (or rather aeson), which shouldn't be on your worry list.

If you want to be overly-paranoic, create a newtype (over Maybe) for your field so the parsing always succeed, and test later in the application code.

CGenie commented 6 days ago

Well, I don't see a but in postgresql-simple. It's just the jsonb for some reason (code updates, 3rd party injection) does contain a JSON but it's not in the format that Haskell expects.

The newtype hint seems ok, thanks!